These are the notes to a short tutorial I gave to my working group as part of our groundwork group meetings. Some parts here require GNU Bash [1].
echo "foobar"
echo foobar
echo echo # second echo not executed but printed!
echo foobar | xargs echo # same output as echo foobar
echo foo > test.txt # pipe into file, replacing the content echo bar >> test.txt # append to file # warning: cat test.txt > test.txt # defined as generating an empty file!
echo foobar | sed s/foo.*/foo/ | xargs echo # same output as echo foo
echo foo | grep bar # empty echo foobar | grep oba # foobar, oba higlighted
foo=1 # no spaces around the equal sign! echo ${foo} # "$foo" == "1", "$foobar" == "", "${foo}bar" == "1bar"
echo $(echo foobar) # equivalent to echo foobar | xargs echo
for i in a b c; do echo $i done # ; can replace a linebreak for i in a b c; do echo $i; done
for i in {1..5}; do # 1 2 3 4 5 echo $i done
while true; do break; done # break: stop # continue: start the loop again
foo=1 echo "${foo}" # 1 echo '${foo}' # ${foo} <- literal string for i in "a b c"; do # quoted: one argument echo ${i}; done # => a b c for i in a b c; do # unquoted: whitespace is separator! echo ${i}; done # a # b # c
# string equality a="foo" b="bar" if [[ x"${a}" == x"${b}" ]] ; then echo a else echo b fi
# other tests if test -z ""; then echo empty fi if [ -z "" ]; then echo same check fi if [ ! -z "not empty" ]; then echo inverse check fi if test ! -z "not empty"; then echo inverse check with test fi if test 5 -ge 2; then echo 5 is greater or equal 2 fi
also check test 1 -eq 1
, and info test
.
#!/usr/bin/env bash echo "Hello World"
chmod +x hello.sh ./hello.sh
echo 1 echo $? # 0: success grep 1 /dev/null # fails echo $? # 1: failure exit 0 # exit a script with success value (no further processing of the script) exit 1 # exit with failure (anything but 0 is a failure)
# info about this script version="shell option parsing example 0.1" # check for the kind of getopt getopt -T > /dev/null if [ $? -eq 4 ]; then # GNU enhanced getopt is available eval set -- `getopt --name $(basename $0) --long help,verbose,version,output: --options hvo: -- "$@"` else # Original getopt is available eval set -- `getopt hvo: "$@"` fi # # actually parse the options # PROGNAME=`basename $0` # ARGS=`getopt --name "$PROGNAME" --long help,verbose,version,output: --options hvo: -- "$@"` # if [ $? -ne 0 ]; then # exit 1 # fi # eval set -- $ARGS # default options HELP=no verbose=no VERSION=no OUTPUT=no # check, if the default wisp exists and can be executed. If not, fall # back to wisp.py (which might be in PATH). if [ ! -x $WISP ]; then WISP="wisp.py" fi while [ $# -gt 0 ]; do case "$1" in -h | --help) HELP=yes;; -o | --output) OUTPUT="$2"; shift;; -v | --verbose) VERBOSE=yes;; --version) VERSION=yes;; --) shift; break;; esac shift done # all other arguments stay in $@ <<using-options>>
# Provide help output if [[ $HELP == "yes" ]]; then echo "$0 [-h] [-v] [-o FILE] [- | filename] Show commandline option parsing. -h | --help) This help output. -o | --output) Save the executed wisp code to this file. -v | --verbose) Provide verbose output. --version) Print the version string of this script. " exit 0 fi if [[ x"$VERSION" == x"yes" ]]; then echo "$version" exit 0 # script ends here fi if [[ ! x"$OUTPUT" == x"no" ]]; then echo writing to $OUTPUT fi # just output all other arguments if [ $# -gt 0 ]; then echo $@ fi
prog [OPTIONAL_FLAG] [OPTIONAL_ARGUMENT VALUE] REQUIRED_ARGUMENT... # ... means that you can specify something multiple times # short and long options prog [-h | --help] [-v | --verbose] [--version] [-f FILE | --file FILE] # concatenated short options hg help [-ec] [THEMA] # hg help -e -c == -ec
prog --help # provide help output. Often also -h prog --version # version of the program. Often also -v prog --verbose # often to give more detailed information. Also --debug
By convention and the minimal GNU standards
echo 1 ; echo 2 ; echo 3 # sequential echo 1 & echo 2 & echo 3 # backgrounding: possibly parallel grep foo test.txt && echo foo is in test.txt # conditional: Only if grep is successful grep foo test.txt || echo foo is not in test.txt # conditional: on failure
echo $((1+2)) # 3 a=2 b=3 echo $((a*b)) # 6 echo $((a**$(echo 3))) # 8
man [command]
info [topic] info [topic subtopic] # emacs: C-h i
more convenient info:
function i() { if [[ "$1" == "info" ]]; then info --usage -f info-stnd else # check for usage from fast info, if that fails check man and if that also fails, just get the regular info page. info --usage -f "$@" 2>/dev/null || man "$@" || info "$@" fi }
Links:
[1] http://gnu.org/s/bash