2017-11-26

shell programming intro

overview of the most useful features

what shell?

the shell command language of the portable operating system interface

short: posix shell, sh

bash/zhs/ksh are sh compatible shells

variables

definition

a=bc
a="bc d"

no space around =

substitution

a="echo test"
$a

-> echo test

"$a"

-> "echo test"

conditionals

conditions use the exit code of commands

if grep -Fq error development.log
then
  # code
elif [ $? -eq 3 ]
  # code
else
  # code
fi

"true" is an application that is usually installed

while true
do
  echo test
done

automatically splits what is after "in" at whitespace

for a in b c d e
do
  echo $a
done

one-liner

for a in *; do echo "$a"; done
while true; do echo test; done

special parameters

array of arguments

$@

last exit code

$?

argument 1, 2, 3, ...

$1
$2
$3

command lists

; ignore exit code

&& continue if exit code is 0

|| continue if exit code is not 0

cd /tmp && echo test || echo xy ; echo z

left associative. evaluated like this

((cd /tmp && echo test) || echo xy) ; echo z

program output redirection

>> append to existing file

> truncate or create file and write

| pipe between standard output and standard input

< read from file

cat filename | tail >> output-file

sub-routines

name() {
  # code ...
}

accessing arguments

name() {
  echo $@
}

round brackets without content

name() {
  echo $1
}

usage

name 3 2 1

commands

operator argument ...

file as command. executes a file

/usr/bin/echo test
./this_file
echo

the last one searches command in the environment variable $PATH

variable as command

a=echo test
$a 3

sub-routine as command

test() {
  process_file > /tmp/output
}

cat filename | test
compress_javascript() {
  uglifyjs --compress --mangle $@
}

cat input.js | compress_javascript > output.js

$@ is used in this example to be able to eventually pass additional arguments to "uglifyjs"

subshells

evaluate shell code and get what would be written on standard output

$()
$(code ...)
timestamp=$(date +%s)

example file content

#!/bin/sh

# links config files to their destinations

install() {
  sources=$@
  cp --recursive --force --symbolic-link --verbose \
    --target-directory=/ $sources
}

if [ $# -eq 0 ]
then
  echo usage example: ./exe/install hostname
else
  install "$PWD/data/$1"/*
fi

explanations

#!/bin/sh is a so called hashbang that is used by the program execution system call to select a program to evaluate the file content with

# creates code comments that will be ignored on the rest of the same line

scripts should have a description at the top so that readers dont need to analyse the code to get an idea of what it is supposed to archieve

use long options like --option so that readers dont have to look into man pages to remind themselves what single character flags like -s or combinations like -rsat stand for

the \ is used to escape a linebreak character and treat what follows on the next line as being on the current line

for statements like "if", put "then" on the following line to not have to add an extra semicolon like "if; then"

$# gives the number of arguments that were used when the current script was called

to execute a file

./filename
sh filename

tags: programming start q1 document guide computer bash tutorial posix shell