Коды состояния оболочки в make - PullRequest
18 голосов
/ 14 апреля 2009

Я использую Makefile (с GNU make, работающим под Linux), чтобы автоматизировать мою грубую работу при рефакторинге скрипта Python. Сценарий создает выходной файл, и я хочу убедиться, что выходной файл остается неизменным перед лицом моих рефакторингов.

Однако я не нашел способа получить код состояния команды, чтобы повлиять на последующую командную оболочку if.

Следующее правило иллюстрирует проблему:

check-cond-codes:
    diff report2008_4.csv report2008_4.csv-save-for-regression-testing; echo no differences: =$$!=
    diff -q poalim report2008_4.csv; echo differences: =$$!=

Первый 'diff' сравнивает два одинаковых файла, а второй сравнивает два разных файла. Выход:

diff report2008_4.csv report2008_4.csv-save-for-regression-testing; echo no differences: =$!=
no differences: ==
diff -q poalim report2008_4.csv; echo differences: =$!=
Files poalim and report2008_4.csv differ
differences: ==

Так очевидно, что «$$!» неправильная переменная для захвата кода состояния diff. Даже используя ОБОЛОЧКА: = / bin / bash в начале Makefile не решил проблему.

Переменная, возвращающая нужное мне значение, будет (если она вообще существует) использоваться в команде if в реальном правиле.

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

Связанный:

Ответы [ 6 ]

36 голосов
/ 14 апреля 2009

Я думаю, что вы ищете переменную оболочки $?, которая дает код завершения предыдущей команды. Например:

$ diff foo.txt foo.txt
$ echo $?
0

Чтобы использовать это в вашем make-файле, вам нужно экранировать $, как в $$?:

all:
    diff foo.txt foo.txt ; if [ $$? -eq 0 ] ; then echo "no differences" ; fi

Обратите внимание, что каждая команда в вашем теле правила в make запускается в отдельной подоболочке. Например, следующее не будет работать:

all:
    diff foo.txt foo.txt
    if [ $$? -eq 0 ] ; then echo "no differences" ; fi

Поскольку команды diff и if выполняются в разных процессах оболочки. Если вы хотите использовать выходной статус из команды, вы должны сделать это в контексте той же оболочки, что и в моем предыдущем примере.

4 голосов
/ 14 апреля 2009

Использовать '$$?' вместо '$$!' (спасибо 4-му ответу Сценарий оболочки выхода на основе кода выхода процесса )

3 голосов
/ 14 апреля 2009

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

Вот почему вы часто видите что-то вроде:

my_target:
    do something \
    do something else \
    do last thing.

И при отладке не забывайте каждую полезную опцию -n, которая будет печатать команды, но не выполнять их, и опцию -p, которая покажет вам полную среду make, включая места, где были установлены различные биты и кусочки.

НТН

ура

2 голосов
/ 11 декабря 2014

Если вы передаете код результата на if, вы можете просто сделать:

all:
    if diff foo.txt foo.txt ; then echo "no differences" ; fi
0 голосов
/ 14 апреля 2009

Попробуйте `\ $? ' Я думаю, что $$ интерпретируется make-файлом

0 голосов
/ 14 апреля 2009

Переменная bash $?, но почему вы все равно хотите распечатать код состояния?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...