Lite skal omdirigering

10 Maj, 2009 av Prashant · Kommentarer
Filed under: teknik

Här är hur vi normalt gör skal omdirigering
$ ./pgm.sh args >out.txt 2>err.txt
Jag ville ändra det lite och kör enligt följande
$ ./pgm.sh args
med kravet att produktionen och fel bör gå till någon filename beräknas inne pgm.sh baserat på args. Man illustrativt fall kan vara när dagen är en del av args. Så du vill stdout gå att säga / din / katalog / pgm_out_YYYYMMDD.txt 1

Problemet med standardiserat sätt att styra N>file.txt dvs associera N filidentifierare till file.txt, är att det fungerar bara för den nyligen kluven processen och inte för den pågående processen.

$ echo hi 1>out.txt ; echo hii . skickar hej till out.txt, men kommer att skrivas ut hii till stdout 2

Det är där exec kommer till vår undsättning. Om vi lägger exec 1>somefile.txt sedan ut från resten av skriptet kommer att gå till somefile.txt

$ cat test.sh
#!/usr/bin/env bash
exec 1>out.txt
echo hi
echo hii
$. / Test.sh omdirigerar hi liksom hii att out.txt

Likaså att omdirigera stdout samt stderr vi göra något sånt här
cat test2.sh
exec 1>out.txt
exec 2>err.txt
echo out text
echo 1>&2 err text
somenoneexitent command
ls -ld /tmp

Nu kommer tillbaka till den ursprungliga punkten omdirigera viss fil från innanför skalet, låt oss säga program beräknas filnamnet i någon rörlig UTFIL kunde vi just har gjort exec 1>$OUTFILE

Som löser det aktuella problemet. Men du kanske vill gå igenom följande exempel som uppnår "random access" av filer i skalskript. Exempel är från här
echo 1234567890 > File # Write string to "File".
exec 3<> File # Open "File" and assign fd 3 to it.
read -n 4 <&3 # Read only 4 characters.
echo -n . >&3 # Write a decimal point there.
exec 3>&- # Close fd 3.
cat File # ==> 1234.67890

Med kommentarer, är denna kod självförklarande.
-
1 Det kan också göras genom $ ./pgm.sh args >pgm_out`date +%Y%m%d` men tanken är att skapa den här filen namn baserat på någon logik i själva programmet.
2 1 1> out.txt är överflödigt, men det klargörs här att vi omdirigerar FD 1