next up previous contents
Nästa: 6.7 Övningar Upp: 6. Skalet Bash Förra: 6.5 Omskrivningar

6.6 Omdirigering

Det är inte svårt att skicka text som indata till ett program. Man kan helt enkelt låta echo skriva ut texten till programmet via en rörledning. Men det finns ett annat sätt, som ibland är bekvämare, nämligen att omdirigera indatan med tecknen <<. I följande exempel skickar vi texten Eva Thulin som indata till programmet hej från sida [*]:$ hej <<EOF
> Eva Thulin
> EOF
Hej, Eva Thulin!
$
Efter tecknen << skriver man ett godtyckligt ord. Ofta väljer man EOF, som står för ''End Of File''. Därefter skriver man den text som ska utgöra kommandots indata. Man avslutar med att på en ny rad skriva samma ord som man skrev efter tecknen <<. På detta sätt kan indatan till ett kommando skrivas i anslutning till själva kommandot.

#!/bin/bash
TAL=10
cat <<- EOF
        Hej, $1!
        Idag är det den $(date).
        Visste du att $TAL/2=$((TAL/2))?
        Hejdå!
EOF

Programmet hejsan ovan skriver ut fyra rader text med hjälp av cat. För att göra programmet lättläst har vi satt ett tabulatorsteg före varje rad av texten. Minustecknet efter tecknen << är en signal till skalet att dessa tabulatorsteg ska tas bort innan texten skickas genom cat.$ hejsan
Hej, Göran!
Idag är det den sön feb 22 19:01:17 CET 1998.
Visste du att 10/2=5?
Hejdå!
$
Körningen ovan visar att några av de vanliga omskrivningarna kan användas i den text som omdirigeras med <<. Om man beskyddar någon del av ordet efter <<, så undviker skalet dessa omskrivningar.

#!/bin/bash
cat <<- 'EOF'
        Hej, $1!
        Idag är det den $(date).
EOF

Programmet ovan ger följande utskrift:$ hejsan
Hej, $1!
Idag är det den $(date).
$

Man kan koppla samman ett antal kommandon genom att låta dem omges av parenteser. Därigenom får kommandona en gemensam in- och utdata. Betrakta tex följande två kommandon:$ echo -n 'Dagens datum är ' ; date
Dagens datum är sön feb 22 19:18:57 CET 1998
$
Om vi vill skicka utskriften från dessa kommandon genom wc, så kan vi inte göra så här:$ echo -n 'Dagens datum är ' ; date | wc
Dagens datum är       1       6      29
$
Vad som hände var att bara det sista kommandots utdata skickades till wc. Bash prioriterar nämligen operatorn | högre än ;. Med hjälp av parenteser går det bättre:$ (echo -n 'Dagens datum är ' ; date) | wc
      1       9      45
$
Kommandon som kopplats samman med hjälp av parenteser exekveras i ett subskal. Detta innebär att eventuella förändringar av variabelvärden eller nuvarande katalog mellan parenteserna inte är bevarade efter att kommandona kört färdigt. Om man vill att kommandona ska köras i det nuvarande skalet i stället för i ett subskal, så ska man använda klamrar i stället för parenteser; det sista kommandot måste då avslutas med ett semikolon.$ pwd
/home/göran/dikter
$ ( cd /etc ; ls -l passwd )
-rw-r--r--   1 root     root         1291 nov 25 14:37 passwd
$ pwd
/home/göran/dikter
$ { cd /tmp ; ls ; }
emacs.gz
$ pwd
/tmp
$
Ändringen av den nuvarande katalogen skedde i ett subskal i det första exemplet, och då bevarades inte ändringen. Den andra gången bevarades dock ändringen.

Ett annat skäl att koppla samman kommandon så här är att de då kan köras efter varandra i bakgrunden. Nedan startar vi två jobb i bakgrunden; det första väntar i 30 sekunder och skriver därefter ut vilka filer som finns i den nuvarande katalogen, medan det andra dekomprimerar filen emacs.gz.$ (sleep 30 ; ls ) &
[1] 7842
$ gunzip emacs.gz &
[2] 7844
$ jobs
[1]-  Running                 ( sleep 30; ls -NF --color ) &
[2]+  Running                 gunzip emacs.gz & 
$ echo Nu emacs*
är det klart
Nu är det klart
[1]-  Done                    ( sleep 30; ls -NF --color )
[2]+  Done                    gunzip emacs.gz
$
Vid kommandot jobs ovan ser man att de båda jobben är i full gång. Men medan jag skrev in nästa kommando, kom utskriften av ls från första jobbet emellan. Obekymrad om detta fullbordade jag mitt kommando, echo Nu är det klart. Innan nästa prompt skrevs ut gav Bash besked om att de båda jobben var klara. (Faktum är att jobb nummer två måste ha blivit klart före jobb nummer 1 eftersom ls inte skrev ut emacs.gz.)


next up previous contents
Nästa: 6.7 Övningar Upp: 6. Skalet Bash Förra: 6.5 Omskrivningar
Goran Andersson
1999-03-08