начиная с внешнего перенаправления: ( .. ) 3>&1 1>&2
, важен порядок:
- fd 3 открыт для записи как дубликат 1 (стандартный вывод: здесь это канал ввода)
- , затем fd 1 сокрушается как дубликат 2 (stderr) (или перенаправляется на stderr)
вход |
является тогда fd 3, тогда как stderr не захватывается тройником,
Вложенное перенаправление:
- fd 2 перенаправляется на stdout (который был перенаправлен на внешний stderr)
fd 1 перенаправляется на fd 3 (которыйбыл перенаправлен на внешний stdout)
, поскольку выходные данные дубликатов тройника регистрируются (окончательное перенаправление >final.log 2>&1
, так как fd 2 открыт после fd 1, они оба перенаправлены на final.log) файл final.log будетсодержит программу stdout и stderr, но output.log только stdout.
Может быть, это можно было бы написать проще, используя 3>&1 1>&2 2>&3
, который изменяет stdout и stderr.
Следующеедолжен сделать то же самое:
( pg.sh | tee output.log ) >final.log 2>&1
Следующее пишет программа stdoutв файл output.log stderr в файл error.log и оба в файл final.log.
( ( pg.sh | tee output.log ) 3>&1 1>&2 2>&3 | tee error.log ) >final.log 2>&1