Перенаправление и статус выхода
Модераторы: /dev/random, Модераторы разделов
- Bizdelnick
- Модератор
- Сообщения: 20752
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Перенаправление и статус выхода
Дано: command1 | command2, POSIX shell.
Нужно получить статус выхода command1. Можно ли это сделать как-то кроме как используя именованый канал? (Особых противопоказаний против именованого канала нет, интерес скорее спортивный.)
Нужно получить статус выхода command1. Можно ли это сделать как-то кроме как используя именованый канал? (Особых противопоказаний против именованого канала нет, интерес скорее спортивный.)
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: Перенаправление и статус выхода
может так?
command1 | tee output.1 | command2
command1 | tee output.1 | command2
- Bizdelnick
- Модератор
- Сообщения: 20752
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Перенаправление и статус выхода
А откуда статус выхода брать? В $? будет для command2, а нужен для command1.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: Перенаправление и статус выхода
а я понял. нужен результат завершения первой команды, а не то что она возможно кидает в вывод.
- Bizdelnick
- Модератор
- Сообщения: 20752
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Перенаправление и статус выхода
Именно.
Приходит в голову решение создать анонимный пайп, ассоциированный с файловым дескриптором, и передавать вывод через него, но возможно ли это в принципе сделать на шелле?
То есть что-то вродетолько без mkfifo.
Приходит в голову решение создать анонимный пайп, ассоциированный с файловым дескриптором, и передавать вывод через него, но возможно ли это в принципе сделать на шелле?
То есть что-то вроде
Код: Выделить всё
mkfifo my.fifo
command2 <my.fifo &
command1 >my.fifo
r=$?
rm my.fifo
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: Перенаправление и статус выхода
Код: Выделить всё
$ ls /bla | grep Do
ls: невозможно получить доступ к /bla: Нет такого файла или каталога
$ echo $PIPESTATUS[0]
2[0]
$ ls | grep Do
Documents
Downloads
$ echo $PIPESTATUS[0]
0[0]
$ ls /bla | grep Do
ls: невозможно получить доступ к /bla: Нет такого файла или каталога
$ echo ${PIPESTATUS[*]}
2 1
$ ls | grep Do
Documents
Downloads
$ echo ${PIPESTATUS[*]}
0 0
Re: Перенаправление и статус выхода
Bizdelnick писал(а): ↑29.04.2015 16:27только без mkfifo.Код: Выделить всё
mkfifo my.fifo command2 <my.fifo & command1 >my.fifo r=$? rm my.fifo
я понял что здесь прикол в том что у нас как бы порядок команд меняется и хотя это ничего не меняет по сути, зато мы запускаем первую команду второй и получаем именно ее код завершения. правильно?
- Bizdelnick
- Модератор
- Сообщения: 20752
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Перенаправление и статус выхода
Спасибо, только у меня
Ну да.
Переносимость критична.
Ну да.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
- Hephaestus
- Сообщения: 3729
- Статус: Многоуважаемый джинн...
- ОС: Slackware64-14.1/14.2
- Контактная информация:
Re: Перенаправление и статус выхода
Bizdelnick писал(а): ↑29.04.2015 15:51Можно ли это сделать как-то кроме как используя именованый канал?
Раз уж интерес спортивный, вот нагуглилось обсуждение, полюбопытствуйте.
Там предложено несколько вариантов, в том числе и такие, как в этой теме.
Есть громоздкие и не очень. Есть башизмы, но насколько я разглядел, там не только башизмы.
- Bizdelnick
- Модератор
- Сообщения: 20752
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Перенаправление и статус выхода
Hephaestus писал(а): ↑29.04.2015 22:03Есть громоздкие и не очень. Есть башизмы, но насколько я разглядел, там не только башизмы.
Спасибо. Соорудил по мотивам одного из ответов:
Код: Выделить всё
exec 4>&1
r=`((command1 ; echo $? >&3) | command2) 3>&1 >&4`
exec 4>&-
Осталось разобраться, как это работает...
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: Перенаправление и статус выхода
http://www.opennet.ru/docs/RUS/bash_script...ide/c11620.html
Это колдунство с дескрипторами. Ассоциируем дескриптор 4 с stdout, в 3-й сохраняем код завершения command1, выводим его и перенапрпвляем stdout и stderr в 4. Закрываем дескриптор.
- Bizdelnick
- Модератор
- Сообщения: 20752
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Перенаправление и статус выхода
Вот этот момент всё-таки не до конца понятен. В какой момент открывается 3 дескриптор? Если он дублирует 1, как и 4, то почему они оказываются неравноценны?
Spoiler
И, блин, почему в шелле нет простого и понятного аналога pipe(2)?
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: Перенаправление и статус выхода
Имхо они равноценны, но используются каждый по-своему.
- Bizdelnick
- Модератор
- Сообщения: 20752
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Перенаправление и статус выхода
Ок, переформулирую: почему они — не одно и то же? Развене эквивалентно?
Разве в результатедескрипторы 3 и 4 ведут в разные места?
Код: Выделить всё
4>&1
Код: Выделить всё
dup2(1, 4);
Разве в результате
Код: Выделить всё
dup2(1, 4);
dup2(1, 3);
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
- /dev/random
- Администратор
- Сообщения: 5282
- ОС: Gentoo
Re: Перенаправление и статус выхода
Bizdelnick писал(а): ↑30.04.2015 18:54Ок, переформулирую: почему они — не одно и то же? Развене эквивалентноКод: Выделить всё
4>&1
?Код: Выделить всё
dup2(1, 4);
Эквивалентно.
Bizdelnick писал(а): ↑30.04.2015 18:54Разве в результатедескрипторы 3 и 4 ведут в разные места?Код: Выделить всё
dup2(1, 4); dup2(1, 3);
Если эти команды дать друг за другом, то в одно. Но в примере они даются в разных процессах (подоболочках), и дескриптор 1 в них ведёт в разные места, а значит и дескрипторы 3 и 4 тоже будут вести в разные.
Спасибо сказали:
- Bizdelnick
- Модератор
- Сообщения: 20752
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: Перенаправление и статус выхода
/dev/random писал(а): ↑05.05.2015 15:19в примере они даются в разных процессах (подоболочках), и дескриптор 1 в них ведёт в разные места
А, вот оно что! Я почему-то думал, что дескриптор 1 наследуется сабшеллом, хотя в данном случае это явно не так.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |