оболочка unix, получение кода выхода с дочерним каналом - PullRequest
7 голосов
/ 17 мая 2010

Допустим, я делаю это в оболочке Unix

$ some-script.sh | grep mytext

$ echo $?

это даст мне код выхода grep

но как я могу получить код выхода some-script.sh

EDIT

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

Ответы [ 5 ]

5 голосов
/ 17 мая 2010

Есть несколько решений, это зависит от того, что именно вы хотите сделать.

Самый простой и понятный способ - отправить вывод в файл, а затем сохранить его после сохранения кода выхода:

tmpfile=$(mktemp)
./some-script.sh > $tmpfile
retval=$?
grep mytext $tmpfile
rm tmpfile
4 голосов
/ 25 января 2011

Трюк из comp.unix.shell FAQ (# 13) объясняет, как использование конвейера в оболочке Bourne должно помочь достичь желаемого:

   You need to use a trick to pass the exit codes to the main
   shell.  You can do it using a pipe(2). Instead of running
   "cmd1", you run "cmd1; echo $?" and make sure $? makes it way
   to the shell.

   exec 3>&1
   eval `
     # now, inside the `...`, fd4 goes to the pipe
     # whose other end is read and passed to eval;
     # fd1 is the normal standard output preserved
     # the line before with exec 3>&1
     exec 4>&1 >&3 3>&- 
     {
       cmd1 4>&-; echo "ec1=$?;" >&4
     } | {
       cmd2 4>&-; echo "ec2=$?;" >&4
     } | cmd3
     echo "ec3=$?;" >&4
2 голосов
/ 11 ноября 2012

Существует утилита с именем mispipe, которая входит в пакет moreutils .

Это именно так: mispipe some-script.sh 'grep mytext'

2 голосов
/ 17 мая 2010

Если вы используете bash:

PIPESTATUS
    An array variable (see Arrays) containing a list of exit status values from the processes in the most-recently-executed foreground pipeline (which may contain only a single command). 
0 голосов
/ 23 августа 2013

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

(your_script.sh.pl.others; echo $? >/tmp/myerr)|\ #subshell with exitcode saving
grep sh #next piped commands
exitcode=$(cat /tmp/myerr) #restore saved exitcode
echo $exitcode  #and print them

другой подход, представленный Рэнди выше, более простая реализация кода:

some-script.sh | grep mytext
echo ${PIPESTATUS[0]} #print exitcode for first commands. tables are indexted from 0

это все. оба работают под Bash (я знаю, Bashizm). удачи :) оба подхода не сохраняют временную трубу в физический файл, только код выхода.

...