Перенаправление и статус выхода

На самом деле это единственный раздел про unix на этом форуме

Модератор: /dev/random

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15761
Статус: grammatikführer
ОС: Debian GNU/Linux

Перенаправление и статус выхода

Сообщение Bizdelnick » 29.04.2015 15:51

Дано: command1 | command2, POSIX shell.
Нужно получить статус выхода command1. Можно ли это сделать как-то кроме как используя именованый канал? (Особых противопоказаний против именованого канала нет, интерес скорее спортивный.)
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
nerve
Сообщения: 267
ОС: OpenBSD

Re: Перенаправление и статус выхода

Сообщение nerve » 29.04.2015 16:07

может так?
command1 | tee output.1 | command2

Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15761
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Перенаправление и статус выхода

Сообщение Bizdelnick » 29.04.2015 16:15

А откуда статус выхода брать? В $? будет для command2, а нужен для command1.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
nerve
Сообщения: 267
ОС: OpenBSD

Re: Перенаправление и статус выхода

Сообщение nerve » 29.04.2015 16:17

а я понял. нужен результат завершения первой команды, а не то что она возможно кидает в вывод.
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15761
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Перенаправление и статус выхода

Сообщение Bizdelnick » 29.04.2015 16:27

Именно.
Приходит в голову решение создать анонимный пайп, ассоциированный с файловым дескриптором, и передавать вывод через него, но возможно ли это в принципе сделать на шелле?
То есть что-то вроде

Код: Выделить всё

mkfifo my.fifo
command2 <my.fifo &
command1 >my.fifo
r=$?
rm my.fifo
только без mkfifo.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
nerve
Сообщения: 267
ОС: OpenBSD

Re: Перенаправление и статус выхода

Сообщение nerve » 29.04.2015 16:42

Код: Выделить всё

$ 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
Спасибо сказали:

Аватара пользователя
nerve
Сообщения: 267
ОС: OpenBSD

Re: Перенаправление и статус выхода

Сообщение nerve » 29.04.2015 16:53

Bizdelnick писал(а):
29.04.2015 16:27

Код: Выделить всё

mkfifo my.fifo
command2 <my.fifo &
command1 >my.fifo
r=$?
rm my.fifo
только без mkfifo.

я понял что здесь прикол в том что у нас как бы порядок команд меняется и хотя это ничего не меняет по сути, зато мы запускаем первую команду второй и получаем именно ее код завершения. правильно?
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15761
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Перенаправление и статус выхода

Сообщение Bizdelnick » 29.04.2015 16:55

Спасибо, только у меня
Bizdelnick писал(а):
29.04.2015 15:51
POSIX shell.
Переносимость критична.

nerve писал(а):
29.04.2015 16:53
я понял что здесь прикол в том что у нас как бы порядок команд меняется и хотя это ничего не меняет по сути, зато мы запускаем первую команду второй и получаем именно ее код завершения. правильно?

Ну да.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
Hephaestus
Сообщения: 2578
Статус: Многоуважаемый джинн...
ОС: Slackware64-14.1/14.2

Re: Перенаправление и статус выхода

Сообщение Hephaestus » 29.04.2015 22:03

Bizdelnick писал(а):
29.04.2015 15:51
Можно ли это сделать как-то кроме как используя именованый канал?
Bizdelnick писал(а):
29.04.2015 15:51
интерес скорее спортивный
Раз уж интерес спортивный, вот нагуглилось обсуждение, полюбопытствуйте.
Там предложено несколько вариантов, в том числе и такие, как в этой теме.
Есть громоздкие и не очень. Есть башизмы, но насколько я разглядел, там не только башизмы.
Пускай скрипят мои конечности.
Я - повелитель бесконечности...
Мой блог
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15761
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Перенаправление и статус выхода

Сообщение Bizdelnick » 29.04.2015 22:56

Hephaestus писал(а):
29.04.2015 22:03
Есть громоздкие и не очень. Есть башизмы, но насколько я разглядел, там не только башизмы.

Спасибо. Соорудил по мотивам одного из ответов:

Код: Выделить всё

exec 4>&1
r=`((command1 ; echo $? >&3) | command2) 3>&1 >&4`
exec 4>&-

Осталось разобраться, как это работает...
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
yars
Сообщения: 1144
Статус: Slacker!
ОС: Slackware64-current

Re: Перенаправление и статус выхода

Сообщение yars » 29.04.2015 23:29

Bizdelnick писал(а):
29.04.2015 22:56
Осталось разобраться, как это работает...

http://www.opennet.ru/docs/RUS/bash_script...ide/c11620.html
Это колдунство с дескрипторами. Ассоциируем дескриптор 4 с stdout, в 3-й сохраняем код завершения command1, выводим его и перенапрпвляем stdout и stderr в 4. Закрываем дескриптор.
Slackware64-current/Xfce 4.12/Acer TravelMate 5760
-------------
Registered Linux User #557010
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15761
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Перенаправление и статус выхода

Сообщение Bizdelnick » 30.04.2015 14:44

yars писал(а):
29.04.2015 23:29
в 3-й сохраняем код завершения command1, выводим его

Вот этот момент всё-таки не до конца понятен. В какой момент открывается 3 дескриптор? Если он дублирует 1, как и 4, то почему они оказываются неравноценны?
Spoiler
И, блин, почему в шелле нет простого и понятного аналога pipe(2)?
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
yars
Сообщения: 1144
Статус: Slacker!
ОС: Slackware64-current

Re: Перенаправление и статус выхода

Сообщение yars » 30.04.2015 18:26

Имхо они равноценны, но используются каждый по-своему.
Slackware64-current/Xfce 4.12/Acer TravelMate 5760
-------------
Registered Linux User #557010
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15761
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Перенаправление и статус выхода

Сообщение Bizdelnick » 30.04.2015 18:54

Ок, переформулирую: почему они — не одно и то же? Развене эквивалентно

Код: Выделить всё

dup2(1, 4);
?
Разве в результате

Код: Выделить всё

dup2(1, 4);
dup2(1, 3);
дескрипторы 3 и 4 ведут в разные места?
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

Аватара пользователя
/dev/random
Администратор
Сообщения: 4866
ОС: Gentoo

Re: Перенаправление и статус выхода

Сообщение /dev/random » 05.05.2015 15:19

Bizdelnick писал(а):
30.04.2015 18:54
Ок, переформулирую: почему они — не одно и то же? Развене эквивалентно

Код: Выделить всё

dup2(1, 4);
?

Эквивалентно.

Bizdelnick писал(а):
30.04.2015 18:54
Разве в результате

Код: Выделить всё

dup2(1, 4);
dup2(1, 3);
дескрипторы 3 и 4 ведут в разные места?

Если эти команды дать друг за другом, то в одно. Но в примере они даются в разных процессах (подоболочках), и дескриптор 1 в них ведёт в разные места, а значит и дескрипторы 3 и 4 тоже будут вести в разные.
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 15761
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: Перенаправление и статус выхода

Сообщение Bizdelnick » 05.05.2015 15:44

/dev/random писал(а):
05.05.2015 15:19
в примере они даются в разных процессах (подоболочках), и дескриптор 1 в них ведёт в разные места

А, вот оно что! Я почему-то думал, что дескриптор 1 наследуется сабшеллом, хотя в данном случае это явно не так.
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали: