Posts

Showing posts with the label Shell Script

Bash Throws Error, Line 8: $1: Unbound Variable

Answer : set -u will abort exactly as you describe if you reference a variable which has not been set. You are invoking your script with no arguments, so get_percent is being invoked with no arguments, causing $1 to be unset. Either check for this before invoking your function, or use default expansions ( ${1-default} will expand to default if not already set to something else). This is the effect of set -u . You could check $# inside the function and avoid referencing $1 if it is not set. With $# you can access the number of parameters. In global context it is the number of parameters to the script, in a function it is the number of parameters to the function. In the context of the question, it is if [ $# -ge 1 ] && [ -n "$1" ] then df -h $1 | tail -n +2 | awk '{ print $1,"\t",$5 }' else df -h | tail -n +2 | awk '{ print $1,"\t",$5 }' fi Note that you have to use [ $# -ge 1 ] && [ -n "$...

Binary To Hexadecimal And Decimal In A Shell Script

Answer : It's fairly straightforward to do the conversion from binary in pure bash ( echo and printf are builtins): Binary to decimal $ echo "$((2#101010101))" 341 Binary to hexadecimal $ printf '%x\n' "$((2#101010101))" 155 Going back to binary using bash alone is somewhat more complex, so I suggest you see the other answers for solutions to that. Assuming that by binary, you mean binary data as in data with any possible byte value including 0, and not base-2 numbers: To convert from binary, od (standard), xxd (comes with vim ) or perl 's unpack come to mind. od -An -vtu1 # for decimal od -An -vtx1 # for hexadecimal xxd -p # for hexa perl -pe 'BEGIN{$\="\n";$/=\30};$_=unpack("H*",$_)' # like xxd -p # for decimal: perl -ne 'BEGIN{$\="\n";$/=\30;$,=" "}; print unpack("C*",$_)' Now, to convert back to binary, awk (standard), xxd -r or perl 's pack : ...

#!/bin/bash - No Such File Or Directory

Answer : This kind of message is usually due to a bogus shebang line, either an extra carriage return at the end of the first line or a BOM at the beginning of it. Run: $ head -1 yourscript | od -c and see how it ends. This is wrong: 0000000 # ! / b i n / b a s h \r \n This is wrong too: 0000000 357 273 277 # ! / b i n / b a s h \n This is correct: 0000000 # ! / b i n / b a s h \n Use dos2unix (or sed , tr , awk , perl , python …) to fix your script if this is the issue. Here is one that will remove both of a BOM and tailing CRs: sed -i '1s/^.*#//;s/\r$//' brokenScript Note that the shell you are using to run the script will slightly affect the error messages that are displayed. Here are three scripts just showing their name ( echo $0 ) and having the following respective shebang lines: correctScript: 0000000 # ! / b i n / b a s h \n scriptWithBom...

Bash - Integer Expression Expected

Answer : The test command, also named [ , has separate operators for string comparisons and integer comparisons: INTEGER1 -eq INTEGER2 INTEGER1 is equal to INTEGER2 vs STRING1 = STRING2 the strings are equal and STRING1 != STRING2 the strings are not equal Since your data is not strictly an integer, your test needs to use the string comparison operator. The last realization in the comments was that the "-eq" logic did not match the sense of the if/else echo statements, so the new snippet should be: ... if [ "$x" != "$y" ] then echo There is version $y update else echo Version $x is the latest version fi BTW, if you have two version strings (e.g. in $x and $y ) you can use printf and GNU sort to find which is newer. $ x=4.1.1 $ y=4.2.2 $ printf "%s\n" "$x" "$y" | sort -V -r 4.2.2 4.1.1 $ if [ $(printf "%s\n" "$x" "$y" | sort -V -r | head -1) = "$x...

Avoiding Busy Waiting In Bash, Without The Sleep Command

Answer : In newer versions of bash (at least v2), builtins may be loaded (via enable -f filename commandname ) at runtime. A number of such loadable builtins is also distributed with the bash sources, and sleep is among them. Availability may differ from OS to OS (and even machine to machine), of course. For example, on openSUSE, these builtins are distributed via the package bash-loadables . Edit: fix package name, add minimum bash version. Creating a lot of subprocesses is a bad thing in an inner loop. Creating one sleep process per second is OK. There's nothing wrong with while ! test_condition; do sleep 1 done If you really want to avoid the external process, you don't need to keep the fifo open. my_tmpdir=$(mktemp -d) trap 'rm -rf "$my_tmpdir"' 0 mkfifo "$my_tmpdir/f" while ! test_condition; do read -t 1 <>"$my_tmpdir/f" done I recently had a need to do this. I came up with the following function that will al...