Получить код возврата программы 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

$? дает возвращаемое значение последней выполненной команды.