echo Hello world
printf 'Hello world!\n'
#! /bin/sh printf "hva heter du? " read navn echo "hei $navn"
Når du starter et program vil det få input og output.
Kjører du programmet interaktivt vil input og output gå til «terminalen» du starter programmet fra. Ved å bruke redirigreingsoperatorene kan vi styre input og output til andre steder:
> fil
>> fil
< fil
tr -d '\r' <dosfil >unixfil
ls >> filer
prog1 | prog2
Analogien er at vi hekter et «rør» fra ut-hullet på det ene programmet til inn-hullet på det andre programmet. På denne måten kan vi lage lange «pipelines» med programmer.
Et filter er et program som er beregnet til å stå i en pipe. Det får input, gjør noe med denne og sender resultatet ut. Du kan dermed se på programene bortover pipen som statements som gjør noe med dataene som strømmer igjennom. Filtre er ofte (men ikke alltid) linjebaserte.
Under følger en del programmer som er nyttige som filtre, og beskrivelse av hva du kan gjøre med dem. For å få full oversikt, se mansiden til hvert enkelt program.
man grep
grep geitemat Mailbox mail/*
ypcat passwd | grep Lise
wc exphil/modul2.txt
ypcat passwd | grep ':/bin/bash$' | wc -l
ypcat passwd | cut -f7 -d: | grep bash | wc -l
du -S | sort -nr | less
ypcat passwd | cut -f7 -d: | sort | uniq
ypcat passwd | cut -f7 -d: | sort | uniq -c | sort -nr
ypcat passwd | cut -f5 -d: | tr '{|}[\\]' 'æøåÆØÅ' | sort
ypcat passwd | cut -f5 -d: | cut -f1 -d, | tr '{|}[\\]' 'æøåÆØÅ' | awk '{print $NF,$0}' | sort | awk '{print $2,$3,$4,$5,$6,$7}' > navneliste
pattern { action }
iostat 1 500 | awk 'NR>2 {total++; if ($4 > 0) buzy++; } END {print buzy/sum }'
awk 'BEGIN {produkt=1} {produkt*=$1} END {print produkt}'
sed 's/NTH/NTNU/g'
Liksom-grep:
sed -n '/regexp/p'
grep regexp
cat kapittel*.xml > bok.xml
tail logfil | tac | less
make | tee makelog
find /home/prosjekt -mtime -1 -print | wc
find . -name core -print | xargs rm
find . -name core -print0 | xargs -0 rm
$ seq 4 1 2 3 4
for i in $(seq 99 0); do echo "$i kagger med øl på en hylle..." done
steinarh lizard:ttyp6 Nov 8 11:22 :05
rwho | wc
rwho -a | wc
rwho -a | cut -f1 -d\ | sort | uniq | wc
rwho -a | cut -f1 -d\ | sort | uniq -c | sort -nr | less
rwho -a | awk '{print $2}' | cut -f1 -d: | sort | uniq -c | sort -nr
; & || &&
;
&
||
||
bare dersom det før feilet.
&&
&&
bare dersom det før gikk bra.
ls ; date
ls date
$ true $ echo $? 0 $ false $ echo $? 1
true og false er to småprogrammer hvis eneste oppgave er å hhv lykkes og feile. $? er en magisk variabel med returverdien til der forrige programmet som ble kjørt (startet).
Det er vanlig å ha :
som et internt alias for true.
Test er et program som tester en ting og returnerer true eller false utifra om det stemmer eller ikke.
Noen få av tingene test kan teste:-e fil
-d fil
-f fil
-r fil
-w fil
-x fil
-s fil
fil1 -nt fil2
fil1 -ot fil2
fil1 -ef fil2
-z streng
-n streng
streng
! expr
expr1 -o expr2
expr1 -a expr2
num1 -eq num2
num1 -ne num2
num1 -lt num2
num1 -le num2
num1 -gt num2
num1 -ge num2
test -f logfil && cp logfil logfil.bak
Test kan også startes som [
, og forventer da å finne
en ]
å slutten av argumentlista si.
[ -n "$foo" ] && bar="$foo"
for variabel in ord ... do ... done
cd /var/log for file in syslog printerlog maillog; do [ -f $file.2 ] && mv $file.2 $file.3 [ -f $file.1 ] && mv $file.1 $file.2 [ -f $file ] && mv $file $file.1 done
if betingelse then ... fi
else
og elif
sammen med
if
.
if [ -z "$foo" ]; then if [ -n "$bar" ]; then foo="$bar" elsif [ -n "$baz" ]; then foo="$baz" else foo=default fi fi
while betingelse do ... done
while true; do cat vekkeklokke.au > /dev/audio sleep 10 done
case ord in uttrykk) ... ;; esac
case $filnavn in *.gif|*.jpeg|*.png) xv $filnavn ;; *.mp3) mpg123 $filnavn ;; *.avi) mplayer $filnavn ;; *) echo "Unknown filetype" 1>&2 ;; esac
blopp() { echo "her er jeg" }
$0
$1 $2...
shift
$1=$2 $2=$3 ...
$*
"$@"
"$1" "$2" ...
)ls() { local file for file in *; do echo $file done }
cat() { local file line for file in "$@"; do while read line; do echo $line done < $file done }
( sleep 1; rm /notexists ; true ) >/dev/null 2>&1 || echo jada { sleep 1; rm /notexists ; true; } >/dev/null 2>&1 || echo jada
$( ) ` `
$(( ))
${ }
echo Du har følgende filer i denne katalogen: $(ls)
c=$(( $a + $b * 3 ))
#! /bin/sh condmv() { [ -f "$1" ] && mv "$1" "$2" } cd /var/log for file in "$@"; do for e in $(seq 5 1); do condmv "$file.$e" "$file.$(($e + 1))" done condmv "$file" "$file.1" done kill -HUP "$(cat /var/run/syslog.pid)"
echo super${var}plosjon
${#parameter}
${parameter%word}
${parameter%%word}
${parameter#word}
${parameter##word}
for i in *.pnm; do convert $i ${i%%.pnm}.jpeg done
${parameter:-word}
${parameter:=word}
${parameter:?feilmelding}
${parameter:+word}
navn=${navn:-"$USER"}
$ echo k[uy]rs-*-del?.ps kurs-globb-del1.ps kurs-globb-del2.ps kyrs--del2.ps
' '
" "
\
$ fisk=sei $ touch seipostei $ echo ${fisk}* seipostei $ echo "${fisk}*" sei* $ echo '${fisk}*' ${fisk}*
$ spam=(foo bar baz) [*] $ echo $spam foo $ echo ${spam[0]} foo $ echo ${spam[2]} baz $ echo ${spam[*]} foo bar baz $ spam[1]=gris; spam[3]=rotte $ echo ${spam[*]} foo gris baz rotte
$ set -- foo bar baz $ echo $1 foo $ echo $3 baz $ echo $* foo bar baz
$$
$!
$?
program & programpid=$! sleep 60 kill $programpid
( sleep 100 ; kill $$) &
kill [ -signal ] pid
kill -l
gir en liste over tilgjengelige signaler.
Hva skjer når du sender et signal til en prosess?
Alle signaler har en default action, som for de fleste signaler går ut på å avslutte (med eller uten coredump), noen ignoreres som default, og noen håndteres av operativsystemet.
Dersom prosessen selv håndterer signalet, kan vi bruke trap for å endre oppførselen når vi mottar dette signalet.
trap action sig ...
tempfil=/tmp/foo.$$ trap "rm -rf $tempfil; exit 1" HUP # gjør noe med $tempfil
trap "echo foo" TERM (sleep 4; kill $$) & echo bar sleep 10 echo baz
wait pid
sleep 10 & p=$! (sleep 4; kill $p) & echo bar wait $p echo baz
Vi har mer enn output og input!
Når vi starter et program arver programmet fildeskriptorer fra mor-prosessen. Vanligvis vil vi da få minst stdout (fildeskriptor nr 0), stdin (1) og stderr (2). (Disse tre blir satt opp på en terminal, og i de fleste andre kontekster et program kjøres fra.)
Stderr unnslipper pipelinen slik at feilmeldingen kan gå direkte til brukeren i stedet for å forsvinne et sted i røret.
fd> fil
fd>> fil
fd< fil
fd1>&fd2
Pass på når du bruker >&
program >/dev/null 2>&1
program 2>&1 | program2
echo foo 3>&1 >/dev/null 1>&3
Noen spesielle skall (f.eks es) bruker = istedet for >&, da er det litt enklere å skjønne. Se på både > og >& som en tilordning til fildeskriptoren til venstre.
Vi kan lure en redirigering til å komme fra en fil:diff -u <(sort /etc/passwd) <(ypcat passwd | sort)
/dev/fd/0 /dev/fd/1 /dev/fd/2 ...
export TMPDIR
FOO=bar prog
OLDIFS="$IFS" IFS="a b" set -- hahahah jeg ler jjjjbhhh echo $* echo "$*" IFS="$OLDIFS"
for i in .qmail* ; do printf '0a\n|spamfilter\n.\nw\n' | ed $i done
for i in *.pnm; do convert $i ${i%%.pnm}.jpeg done
find -name \*.pnm | sed 's/\(.*\).pnm/convert & \1.jpeg/' | sh -x
for i in $(grep -l '^Signature .*steinarh@fm.unit.no' */registration) ; do printf '/^Signature/s/steinarh@fm.unit.no/steinarh@math.ntnu.no/\nw\n' | ed $i done
sed -n 's/^Signature \. \.\.\. \.\.\. : //p' */registration \ | sort | uniq -c | sort -nr > ~/top_ten.txt
.
brukes til å source filer, dvs inkludere
fila i shellscriptet som utført. Dette brukes bl.a. til
oppstartsfiler, men vi kan bruke det til hva som helst, også å source
en fil som nettopp er blitt laget.
input=/tmp/sourcetest.$$ trap "rm -f $input; exit 1" HUP TERM cat > $input . $input rm -f $input
$ grukk=foo $ gaff=bar $ eval "$grukk=$gaff" $ echo $foo bar
while [ $# -gt 0 ]; do case $1 in -i) eval "$2"; shift ;; *) echo "Illegal option \"$1\"" 1>&2 ;; esac shift done
filnavn="/home/lise/mine dokumenter/handleliste.txt" rm $filnavn
rm "$filnavn"
.
Bruk alltid "$@" isteden for $*.
Hvis /var/log/old ikke finnes...
cd /var/log/old rm *
die() { echo "$@" 1>&2 ; exit 1 } cd /var/log/old || die Can't change directory to /var/log/old rm *
... [ -e /tmp/mail_signature ] && { echo "File exists!" 1>&2 ; exit 1 } sed '/^ --/,$p' /tmp/mail_signature ...
while true; do ln -s /etc/passwd /tmp/signature rm /tmp/signature done
http://www.pvv.ntnu.no/~steinarh/shkurs/kurs.html