Получить код возврата программы C в моей программе оболочки
Предположим, у меня есть программа C с именем Foo.c
, которая печатает несколько вещей и возвращает значение с именем rc
, которое я выполняю в своей программе оболочки следующим образом:
foobar=$(Foo | tail -1)
Теперь переменная foobar имеет последнее напечатанное значение программы Foo
. Но, не нарушая этого, я хочу получить код возврата rc
программы в моей программе оболочки.
Ответы
Ответ 1
Вы можете использовать опцию "set -o pipefail".
[[email protected] Test]# set -o pipefail
[[email protected] Test]# ./a.out | tail -l
[[email protected] Test]# echo $?
100
Здесь моя программа a.out возвращает 100.
Или другие опции - использовать переменную окружения pipestatus. Вы можете прочитать об этом здесь.
http://www.linuxnix.com/2011/03/pipestatus-internal-variable.html
Ответ 2
Если вы используете оболочку bash
, вы можете использовать переменную массива PIPESTATUS
, чтобы получить статус процесса pipe
.
$ tail sat | wc -l
tail: cannot open ‘sat’ for reading: No such file or directory
0
$ echo "${PIPESTATUS[0]} ${PIPESTATUS[1]}"
1 0
$
От man bash
:
PIPESTATUS
Переменная массива, содержащая список значений статуса выхода из процессов в наиболее недавно выполненном конвейере переднего плана (который может содержать только одну команду).
Ответ 3
Это назначает последнюю строку вывода Foo
на foobar
, а код выхода Foo присваивается code
:
{ read -r foobar; read code; } < <( (Foo; echo $? ) | tail -2)
Конструкция <(...)
называется подстановкой процесса. В приведенном выше коде команды read
получают свой stdin из подстановки процесса. Из-за tail -2
подстановка процесса дает всего две строки. Первая строка - последняя строка, созданная Foo
, и ей присваивается foobar
. Второй присваивается code
.
Пространство между первым и вторым <
существенно.
Пример
После создания функции Foo выше можно проверить:
$ Foo() { echo "Testing"; false; }
$ { read -r foobar; read code; } < <( (echo "Testing"; false; echo $? ) | tail -2)
$ echo "foobar=$foobar code=$code"
foobar=Testing code=1
и
$ Foo() { echo "2nd Test"; true; }
$ { read -r foobar; read code; } < <( (Foo; echo $? ) | tail -2)
$ echo "foobar=$foobar code=$code"
foobar=2nd Test code=0
Ответ 4
Я боюсь, что вам нужно использовать временный файл для хранения вывода программы Foo, получить код возврата и затем выполнить хвост -1. Точно так же:
Foo > /tmp/temp_file
ret=$?
foobar=$(tail -1 /tmp/temp_file)
Ответ 5
$?
дает возвращаемое значение последней выполненной команды.