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)
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)
Odpowiedzi:
Standard POSIX określa, że przekierowanie powłoki odbywa się od lewej do prawej; to znaczy porządek jest znaczący:
Konstrukcja
2>&1jest 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>&1kieruje zarówno standardowe wyjście, jak i standardowy błąd do pliku
foo. Jednak:ls 2>&1 > footylko kieruje standardowe wyjście do pliku,
fooponieważ 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 | command2wysyła zarówno standardowe wyjście, jak i błąd
command1standardowy na standardowe wejściecommand2.
ls > foo 2>&1oznaczać 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?
bashjest ogólnie zgodny z POSIX, z wyjątkiem opisanych tutaj sytuacji , w których bashzachowanie domyślne jest inne . Aby zwiększyć bashzgodność, możesz użyć tej --posixopcji.
ls > foo 2>&1działa w ten sposób: najpierw standardowe przekierowanie jest przekierowywane do foo, następnie standardowy błąd jest przekierowywany do standardowego wyjścia, którym jest teraz plik foo. Drugi przykład, ls 2>&1 > foodziała w ten sposób: błąd standardowy jest przekierowywany na standardowe wyjście przed przekierowaniem na standardowe wyjście foo, 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 cmd2się stdin i karmi stdout cmd3.
Myślę, czy masz na myśli coś takiego cmd1 | cmd2 | cmd3? Ponieważ twoje cmd2i cmd3są zwykle normalnymi plikami zamiast „cmds”.