~/bin
, functions in .bash_profile
... , & aliases
learn few tools well: shell, editor, scripting language
automate everything,
don't optimize too soon,
pick the right (scripting) language
follow best practices:
usage message,
input validation,
meaningful exit code (0=success, nonzero=failure), ...
clarity and programmer efficiency over computational efficiencySTDIN, STDOUT, SDTERR
in UNIX / Linux always file descriptors 0, 1, 2
< , > , >>
to reroute standard input/output
redirecting SDTERR
: >&
(both) or 2>
(only STDERR)
Pipes ('|'),
&& and
|| ( execute 2nd command if 1st succeds / fails )
ls -al /tmp/foo
cd /tmp/foo || mkdir /tmp/foo; cd /tmp/foo; ls -al
ls -l /tmp >& output || echo "error: cannot list files..."
ls -l /root >& output2 || echo "error: cannot list files..."
myvar='/etc'
or myvar=/etc
but watch for spaces: myvar='sth with spaces'
or myvar=sth\ with\ spaces
echo $myvar2
vs echo $myvar/2
vs echo ${myvar}2
in csh or tcsh : set myvar=/etc
echo $myvar
ls -l ${myvar}/passwd
ls -l $myvar/passwd
n=1
m=$((n + 1 ))
echo "n=$n, m=$m"
find /etc -name passwd 2> /dev/null | tee /dev/tty | wc -l
ps aux | grep -v grep | grep `echo $$`
$?
echo $?
echo $?
tail -13 /etc/hosts tail -13 /etc/hosts | grep -v "^#" tail -13 /etc/hosts | grep -v "^#" | perl -ane 'print $F[1],"\n"' tail -13 /etc/hosts | grep -v "^#" | perl -pe 's/^\S* *//' tail -13 /etc/hosts | grep -v "^#" | awk '{print $2}' tail -13 /etc/hosts | grep -v "^#" | awk '{print $2}' | while read stl do echo $st; done tail -13 /etc/hosts | grep -v "^#" | awk '{print $2}' | while read st; do echo $st; done tail -13 /etc/hosts | grep -v "^#" | awk '{print $2}' | while read st; do echo "ping -c 1 $st | grep 0%"; done tail -13 /etc/hosts | grep -v "^#" | awk '{print $2}' | while read st; do echo "ping -c 1 $st | grep 0%"; done | sh - x tail -13 /etc/hosts | grep -v "^#" | awk '{print $2}' | while read st; do echo "ping -c 1 $st | grep 0%"; done | sh -xalso
for st in `tail -13 /etc/hosts | grep -v "^#" | awk '{print $2}'`; do echo "ping -c 1 $st | grep 0%"; done | sh -xor
for st in `tail -13 /etc/hosts | grep -v "^#" | awk '{print $2}'`; do echo $st; ping -c 1 $st | grep 0%; donewhile loop with counter:
n=1; while [ $n -lt 5 ]; do echo $n; n=$((n + 1)); done
find pathname(s) other_args -print0 | xargs -0 ls -l
or (? better - compare ...)find pathname(s) other_args -exec ls -l {} \;
find . -type f -mtime -10 -name \*.pl -print0 | xargs -0 chmod a+x
find . -type f -mtime -10 -name \*.pl -exec chmod go-x {} \; -ls
#!/bin/bash show_usage(){ ... } if [ $# -ne 2 ]; then show_usage else if [ -d $1 ]; then # 1st argument, $0 - invoked script name elif [ ... ] && [ ... ] ; then else fi fi
var1=1; var2=2; if [ $var1 -lt $var 2 ]; then echo "$var1 is less then $var2"; else echo "$var1 is NOT less then $var2"; fi var1=1; var2=2; if [ $var1 \< $var 2 ]; then echo "$var1 is less then $var2"; else echo "$var1 is NOT less then $var2"; fi var1=a1; var2=a2; if [ $var1 \< $var 2 ]; then echo "$var1 is less then $var2"; else echo "$var1 is NOT less then $var2"; fi
#!/bin/sh cd /tmp for i in 9 8 7 6 5 4 3 2 1 0 ; do j=`expr ${i} + 1` echo "$i -> $j" if [ -f log.${i} ]; then mv log.${i} log.${j} fi done if [ -f log ]; then mv log log.0 else echo "no previous log file found ..." fi touch log chmod 600 logThe 3rd line could also be
for i in `seq 9 -1 0`; doThe 4th line could also be
j=$((i+1))rotate.csh
#!/bin/csh cd /tmp foreach i (9 8 7 6 5 4 3 2 1 0 ) set j = `expr $i + 1` echo "$i -> $j" if ( -f log.${i} ) then mv log.${i} log.${j} endif end if ( -f log ) then mv log log.0 else echo "no previous log file found ..." endif touch log chmod 600 log