La mia domanda è sulla precedenza di reindirizzamento è bash. Supponiamo di avere un comando:
cmd1 < cmd2 > cmd3
Si tradurrebbe in:
(cmd1 < cmd2) > cmd3
O
cmd1 < (cmd2 > cmd3)
La mia domanda è sulla precedenza di reindirizzamento è bash. Supponiamo di avere un comando:
cmd1 < cmd2 > cmd3
Si tradurrebbe in:
(cmd1 < cmd2) > cmd3
O
cmd1 < (cmd2 > cmd3)
Risposte:
Lo standard POSIX specifica che il reindirizzamento della shell è da sinistra a destra; cioè, l'ordine è significativo:
Il costrutto
2>&1viene spesso utilizzato per reindirizzare l'errore standard sullo stesso file dell'output standard. Poiché i reindirizzamenti avvengono dall'inizio alla fine, l'ordine dei reindirizzamenti è significativo. Per esempio:ls > foo 2>&1dirige sia l'output standard sia l'errore standard nel file
foo. Però:ls 2>&1 > foodirige l'output standard su file solo
fooperché l'errore standard è stato duplicato come output standard prima che l'output standard fosse indirizzato al filefoo.
bash opera in conformità con questa parte della norma:
$ ls doesnotexist > foo 2>&1
$ cat foo
ls: cannot access doesnotexist: No such file or directory
$ ls doesnotexist 2>&1 > foo
ls: cannot access doesnotexist: No such file or directory
$ cat foo
$
Per quanto riguarda le tubazioni:
Poiché l'assegnazione della pipeline di input standard o output standard o entrambi avviene prima del reindirizzamento, può essere modificata mediante reindirizzamento. Per esempio:
$ command1 2>&1 | command2invia sia l'output standard sia l'errore
command1standard dell'input standard dicommand2.
ls > foo 2>&1significare reindirizzare stdout a foo quindi reindirizzare stderr a stdout. Quindi questo non dovrebbe funzionare. Allo stesso modo il secondo comando dovrebbe funzionare. Cosa mi sto perdendo qui?
bashè generalmente conforme a POSIX, tranne nelle situazioni descritte qui , in cui il bashcomportamento predefinito differisce. Per rendere bashpiù conforme, è possibile utilizzare l' --posixopzione.
ls > foo 2>&1funziona in questo modo: innanzitutto, l'output standard viene reindirizzato a foo, quindi l'errore standard viene reindirizzato all'output standard, che ora è il file foo. Il secondo esempio ls 2>&1 > foofunziona in questo modo: l'errore standard viene reindirizzato all'output standard prima che venga reindirizzato all'output standard foo, quindi l'errore standard viene ripetuto localmente anziché essere indirizzato al file.
ls 2>&1 >foo forse potresti pensarci così. stderr da 'ls' viene reindirizzato a stdout. Questo accadrà! Andrà a dove stdout è attualmente assegnato, indipendentemente da ulteriori direttive relative a stdout .. (perché questa è la sua prima / prima direttiva ) .. Poi arriva un'altra direttiva che dice che stdout andrà a "pippo", e lo fa ... Ricorda: stderr non viene trasmutato in realtà diventando stdout .. Va solo a dove stdout è stato assegnato al momento della direttiva. (es. il terminal)
Nemmeno io. Una coppia di parentesi indica una sotto-shell. Ma in questo caso, nessuna shell secondaria verrà avviata a causa del reindirizzamento. Bash si nutre semplicemente di cmd2stdin e di stdout cmd3.
Sto pensando, vuoi dire qualcosa del genere cmd1 | cmd2 | cmd3? Perché i tuoi cmd2e di cmd3solito sono file normali invece di "cmds".