Sök…


Syntax

  • kommando </ path / to / file # Omdirigera standardinmatning till fil
  • kommando> / path / to / file # Redirect standard output to flie
  • kommandot file_descriptor> / path / to / file # Redirect output of file_descriptor to file
  • kommando> & file_descriptor # Redirect output till file_descriptor
  • command file_descriptor> & another_file_descriptor # Redirect file_descriptor to another_file_descriptor
  • kommando <& file_descriptor # omdirigera file_descriptor till standardinmatning
  • kommando &> / sökväg / till / fil # Omdirigera standardutdata och standardfel till fil

parametrar

Parameter detaljer
intern filbeskrivning Ett heltal.
riktning En av > , < eller <>
extern filbeskrivning eller sökväg & följt av ett heltal för filbeskrivning eller en sökväg.

Anmärkningar

UNIX-konsolprogram har en inmatningsfil och två utgångsfiler (in- och utgångsströmmar, liksom enheter, behandlas som filer av operativsystemet.) Dessa är vanligtvis tangentbordet respektive skärmen, men alla eller alla av dem kan omdirigeras. att komma från - eller gå till - en fil eller annat program.

STDIN är standardinmatning och är hur programmet får interaktiv inmatning. STDIN tilldelas vanligtvis filbeskrivning 0.

STDOUT är standardutgång. Vad som än släpps ut på STDOUT betraktas som "resultatet" av programmet. STDOUT tilldelas vanligtvis filbeskrivning 1.

STDERR är där felmeddelanden visas. Vanligtvis, när man kör ett program från konsolen, STDERR ut på skärmen och kan inte STDOUT från STDOUT . STDERR tilldelas vanligtvis filbeskrivning 2.

Omdirigeringsordningen är viktig

command > file 2>&1

Omdirigerar både ( STDOUT och STDERR ) till filen.

command 2>&1 > file

Omdirigerar endast STDOUT , eftersom filbeskrivaren 2 omdirigeras till den fil som pekas ut med filbeskrivning 1 (vilket inte är file ännu när uttalandet utvärderas).

Varje kommando i en pipeline har sin egen STDERR (och STDOUT ) eftersom var och en är en ny process. Detta kan skapa överraskande resultat om du förväntar dig att en omdirigering påverkar hela pipeline. Till exempel detta kommando (inslaget för läsbarhet):

$ python -c 'import sys;print >> sys.stderr, "Python error!"' \
| cut -f1 2>> error.log

kommer att skriva ut "Python-fel!" till konsolen snarare än loggfilen. I stället bifogar felet till kommandot du vill fånga:

$ python -c 'import sys;print >> sys.stderr, "Python error!"' 2>> error.log \
| cut -f1 

Omdirigerar standardutgången

> omdirigera standardutgången (aka STDOUT ) för det aktuella kommandot till en fil eller annan beskrivning.

Dessa exempel skriver utdata från ls kommandot i filen file.txt

ls >file.txt
> file.txt ls

Målfilen skapas om den inte finns, annars blir den här filen trunkerad.

Standardomdirigeringsbeskrivningen är standardutdata eller 1 när ingen anges. Detta kommando motsvarar de tidigare exemplen med standardutgången uttryckligen angiven:

ls 1>file.txt

Obs: omdirigeringen initieras av det exekverade skalet och inte av det exekverade kommandot, därför görs det före kommandot exekvering.

Omdirigerar STDIN

< läser från sitt högra argument och skriver till sitt vänstra argument.

För att skriva en fil till STDIN bör vi läsa /tmp/a_file och skriva till STDIN dvs. 0</tmp/a_file

Obs: Intern filbeskrivning är standard 0 ( STDIN ) för <

$ echo "b" > /tmp/list.txt
$ echo "a" >> /tmp/list.txt
$ echo "c" >> /tmp/list.txt
$ sort < /tmp/list.txt
a
b
c

Omdirigerar både STDOUT och STDERR

Filbeskrivare som 0 och 1 är pekare. Vi ändrar vad filbeskrivare pekar på med omdirigering. >/dev/null betyder 1 poäng till /dev/null .

Först pekar vi 1 ( STDOUT ) till /dev/null sedan punkt 2 ( STDERR ) till vad 1 pekar på.

# STDERR is redirect to STDOUT: redirected to /dev/null,
# effectually redirecting both STDERR and STDOUT to /dev/null
echo 'hello' > /dev/null 2>&1
4,0

Detta kan förkortas ytterligare till följande:

echo 'hello' &> /dev/null

Denna form kan emellertid vara oönskad vid produktion om skalkompatibilitet är en oro eftersom den är i konflikt med POSIX, introducerar tolkning av tvetydighet och skal utan denna funktion kommer att tolka den felaktigt:

# Actual code
echo 'hello' &> /dev/null
echo 'hello' &> /dev/null 'goodbye'

# Desired behavior
echo 'hello' > /dev/null 2>&1
echo 'hello' 'goodbye' > /dev/null 2>&1

# Actual behavior
echo 'hello' &
echo 'hello' & goodbye > /dev/null

OBS: &> är känd för att fungera som önskat i både Bash och Zsh.

Omdirigerar STDERR

2 är STDERR .

$ echo_to_stderr 2>/dev/null # echos nothing

Definitioner:

echo_to_stderr är ett kommando som skriver "stderr" till STDERR

echo_to_stderr () {
    echo stderr >&2
}

$ echo_to_stderr
stderr

Lägg till vs Trunkera

Avkorta >

  1. Skapa angiven fil om den inte finns.
  2. Avka (ta bort filens innehåll)
  3. Skriv till fil
$ echo "first line" > /tmp/lines
$ echo "second line" > /tmp/lines

$ cat /tmp/lines
second line

Bifoga >>

  1. Skapa angiven fil om den inte finns.
  2. Lägg till fil (skrivning i slutet av filen).
# Overwrite existing file
$ echo "first line" > /tmp/lines

# Append a second line
$ echo "second line" >> /tmp/lines

$ cat /tmp/lines
first line
second line

STDIN, STDOUT och STDERR förklarade

Kommandon har en ingång (STDIN) och två typer av utgångar, standardutgång (STDOUT) och standardfel (STDERR).

Till exempel:

STDIN

root@server~# read
Type some text here

Standardinmatning används för att tillhandahålla input till ett program. (Här använder vi den read inbyggda för att läsa en linje från STDIN.)

STDOUT

root@server~# ls file
file

Standardutgång används vanligtvis för "normal" utgång från ett kommando. Till exempel ls listar filer, så filerna skickas till STDOUT.

STDERR

root@server~# ls anotherfile
ls: cannot access 'anotherfile': No such file or directory

Standardfel används (som namnet antyder) för felmeddelanden. Eftersom det här meddelandet inte är en lista med filer skickas det till STDERR.

STDIN, STDOUT och STDERR är de tre standardströmmarna. De identifieras i skalet med ett nummer snarare än ett namn:

0 = Standard i
1 = Standard ut
2 = Standardfel

Som standard är STDIN ansluten till tangentbordet och både STDOUT och STDERR visas i terminalen. Vi kan emellertid omdirigera antingen STDOUT eller STDERR till vad vi behöver. Låt oss till exempel säga att du bara behöver standard ut och alla felmeddelanden som skrivs ut på standardfel ska undertrycks. Det är när vi använder beskrivarna 1 och 2 .

Omdirigerar STDERR till / dev / null
Med föregående exempel,

root@server~# ls anotherfile 2>/dev/null
root@server~#

I det här fallet, om det finns någon STDERR, kommer den att omdirigeras till / dev / null (en speciell fil som ignorerar någonting som läggs i den), så att du inte får något fel på skalet.

Omdirigera flera kommandon till samma fil

{
  echo "contents of home directory"
  ls ~
} > output.txt

Använda namngivna rör

Ibland kanske du vill skriva ut något av ett program och mata in det i ett annat program, men kan inte använda ett standardrör.

ls -l | grep ".log"

Du kan helt enkelt skriva till en tillfällig fil:

touch tempFile.txt
ls -l > tempFile.txt
grep ".log" < tempFile.txt

Detta fungerar bra för de flesta applikationer, men ingen kommer att veta vad tempFile gör och någon kan ta bort den om den innehåller output från ls -l i den katalogen. Det är här ett namngivet rör spelar in:

mkfifo myPipe
ls -l > myPipe
grep ".log" < myPipe

myPipe är tekniskt en fil (allt finns i Linux), så låt oss göra ls -l i en tom katalog som vi just skapade ett rör i:

mkdir pipeFolder
cd pipeFolder
mkfifo myPipe
ls -l

Utgången är:

prw-r--r-- 1 root root 0 Jul 25 11:20 myPipe

Lägg märke till det första tecknet i behörigheterna, det är listat som ett rör, inte en fil.

Låt oss göra något coolt.

Öppna en terminal och notera katalogen (eller skapa en så att rensningen är enkel) och skapa ett rör.

mkfifo myPipe

Låt oss nu sätta något i röret.

echo "Hello from the other side" > myPipe

Du kommer att märka att detta hänger, den andra sidan av röret är fortfarande stängd. Låt oss öppna upp den andra sidan av röret och låt det gå igenom.

Öppna en annan terminal och gå till katalogen som röret är i (eller om du vet det, beroende på det på röret):

cat < myPipe

Du kommer att märka att efter att hello from the other side har matats ut slutar programmet i den första terminalen, liksom det i den andra terminalen.

Kör nu kommandona i omvänd riktning. Börja med cat < myPipe och echo sedan något in i den. Det fungerar fortfarande, eftersom ett program kommer att vänta tills något sätts i röret innan det avslutas, eftersom det vet att det måste få något.

Namngivna rör kan vara användbara för att flytta information mellan terminaler eller mellan program.

Rören är små. När det är fullt blockerar författaren tills någon läsare läser innehållet, så du måste antingen köra läsaren och författaren i olika terminaler eller köra den ena eller den andra i bakgrunden:

 ls -l /tmp > myPipe &
 cat < myPipe

Fler exempel med namngivna rör:

  • Exempel 1 - alla kommandon på samma terminal / samma skal

    $ { ls -l && cat file3; } >mypipe &
    $ cat <mypipe    
    # Output: Prints ls -l data and then prints file3 contents on screen
    
  • Exempel 2 - alla kommandon på samma terminal / samma skal

    $ ls -l >mypipe &
    $ cat file3 >mypipe &
    $ cat <mypipe
    #Output: This prints on screen the contents of mypipe. 
    

    Tänk på att först innehållet i file3 visas och sedan visas ls -l data (LIFO-konfiguration).

  • Exempel 3 - alla kommandon på samma terminal / samma skal

    $ { pipedata=$(<mypipe) && echo "$pipedata"; } &
    $ ls >mypipe 
    # Output: Prints the output of ls directly on screen 
    

    Tänk på att variabeln $pipedata inte är tillgänglig för användning i huvudterminalen / huvudskalet eftersom användningen av & åberopar ett underskal och $pipedata endast var tillgängligt i det här underskalet.

  • Exempel 4 - alla kommandon på samma terminal / samma skal

    $ export pipedata
    $ pipedata=$(<mypipe) &
    $ ls -l *.sh >mypipe
    $ echo "$pipedata"   
    #Output : Prints correctly the contents of mypipe
    

    Detta skriver korrekt ut värdet på $pipedata variabeln i huvudskalet på grund av exportdeklarationen för variabeln. Huvudterminalen / huvudskalet hänger inte på grund av att ett bakgrundsskal ( & ) kallas.

Skriv ut felmeddelanden till stderr

Felmeddelanden ingår generellt i ett skript för felsökning eller för att ge en rik användarupplevelse. Skriv bara felmeddelande så här:

cmd || echo 'cmd failed'

kan fungera för enkla fall men det är inte det vanliga sättet. I det här exemplet kommer felmeddelandet att förorena den verkliga utgången från skriptet genom att blanda både fel och framgångsrik utgång i stdout .

Kort sagt ska felmeddelandet gå till stderr not stdout . Det är ganska enkelt:

cmd || echo 'cmd failed' >/dev/stderr

Ett annat exempel:

if cmd; then
    echo 'success'
else
    echo 'cmd failed' >/dev/stderr
fi

I exemplet ovan kommer framgångsmeddelandet att skrivas ut på stdout medan felmeddelandet skrivs ut på stderr .

Ett bättre sätt att skriva ut felmeddelande är att definiera en funktion:

err(){
    echo "E: $*" >>/dev/stderr
}

Nu när du måste skriva ut ett fel:

err "My error message"

Omdirigering till nätverksadresser

2,04

Bash behandlar vissa vägar som speciella och kan göra viss nätverkskommunikation genom att skriva till /dev/{udp|tcp}/host/port . Bash kan inte konfigurera en lyssnande server, men kan initiera en anslutning och för TCP kan läsa resultaten åtminstone.

För att till exempel skicka en enkel webbförfrågan kan man göra:

exec 3</dev/tcp/www.google.com/80
printf 'GET / HTTP/1.0\r\n\r\n' >&3
cat <&3

och resultaten från www.google.com standardwebbplats skrivs ut till stdout .

Liknande

printf 'HI\n' >/dev/udp/192.168.1.1/6666

skickade ett UDP-meddelande som innehåller HI\n till en lyssnare den 192.168.1.1:6666



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow