Moje pytanie dotyczy pierwszeństwa przekierowania to bash. Załóżmy, że masz polecenie:
cmd1 < cmd2 > cmd3
Czy to przełożyłoby się na:
(cmd1 < cmd2) > cmd3
Lub
cmd1 < (cmd2 > cmd3)
źródło
Moje pytanie dotyczy pierwszeństwa przekierowania to bash. Załóżmy, że masz polecenie:
cmd1 < cmd2 > cmd3
Czy to przełożyłoby się na:
(cmd1 < cmd2) > cmd3
Lub
cmd1 < (cmd2 > cmd3)
Standard POSIX określa, że przekierowanie powłoki odbywa się od lewej do prawej; to znaczy porządek jest znaczący:
Konstrukcja
2>&1
jest często używana do przekierowania standardowego błędu do tego samego pliku, co standardowe wyjście. Ponieważ przekierowania odbywają się od początku do końca, kolejność przekierowań jest znacząca. Na przykład:ls > foo 2>&1
kieruje zarówno standardowe wyjście, jak i standardowy błąd do pliku
foo
. Jednak:ls 2>&1 > foo
tylko kieruje standardowe wyjście do pliku,
foo
ponieważ błąd standardowy został zduplikowany jako standardowe wyjście, zanim standardowe wyjście zostało skierowane do plikufoo
.
bash
działa zgodnie z tą częścią normy:
$ 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
$
Jeśli chodzi o orurowanie:
Ponieważ przypisanie potokowe standardowego wejścia lub standardowego wyjścia lub obu odbywa się przed przekierowaniem, można je zmodyfikować przez przekierowanie. Na przykład:
$ command1 2>&1 | command2
wysyła zarówno standardowe wyjście, jak i błąd
command1
standardowy na standardowe wejściecommand2
.
ls > foo 2>&1
oznaczać przekierowania stdout do foo, a następnie przekierowania stderr do stdout. To nie powinno działać. Podobnie drugie polecenie powinno działać. Czego tu brakuje?bash
jest ogólnie zgodny z POSIX, z wyjątkiem opisanych tutaj sytuacji , w którychbash
zachowanie domyślne jest inne . Aby zwiększyćbash
zgodność, możesz użyć tej--posix
opcji.ls > foo 2>&1
działa w ten sposób: najpierw standardowe przekierowanie jest przekierowywane dofoo
, następnie standardowy błąd jest przekierowywany do standardowego wyjścia, którym jest teraz plikfoo
. Drugi przykład,ls 2>&1 > foo
działa w ten sposób: błąd standardowy jest przekierowywany na standardowe wyjście przed przekierowaniem na standardowe wyjściefoo
, więc błąd standardowy jest generowany lokalnie, a nie kierowany do pliku.ls 2>&1 >foo
może możesz pomyśleć o tym w ten sposób. stderr z 'ls' zostaje przekierowany na stdout. To się stanie! Przejdzie do miejsca, w którym aktualnie jest przydzielone stdout , niezależnie od jakichkolwiek dalszych dyrektyw dotyczących stdout .. (ponieważ jest to jego pierwsza / pierwsza dyrektywa ). Potem pojawi się kolejna dyrektywa, która mówi, że stdout przejdzie do „foo”, i robi to ... Pamiętaj: stderr nie przekształca się w stdout. Po prostu idzie tam, gdzie stdout został przypisany w czasie obowiązywania dyrektywy. (np. terminal)Chyba nie. Para nawiasów oznacza podpowłokę. Ale w tym przypadku żadna podpowłoka nie zostanie uruchomiona z powodu przekierowania. Bash po prostu karmi
cmd2
się stdin i karmi stdoutcmd3
.Myślę, czy masz na myśli coś takiego
cmd1 | cmd2 | cmd3
? Ponieważ twojecmd2
icmd3
są zwykle normalnymi plikami zamiast „cmds”.źródło