Коды состояния оболочки в make
Я использую Makefile (с GNU make running под Linux), чтобы автоматизировать мою работу во время рефакторинга Python script.
script создает выходной файл, и я хочу убедиться, что выходной файл остается неизменным в моих рефакторингах.
Тем не менее, я не нашел способа получить код состояния команды, чтобы повлиять на последующую команду shell, если команда.
Следующее правило иллюстрирует проблему:
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".
Даже используя SHELL: =/bin/bash
в начале Makefile не решила проблему.
Переменная, возвращающая значение, которое мне нужно, будет (если оно вообще существует) будет использоваться в команде "if" в реальном правиле.
Альтернатива создания небольшой ad-hoc-оболочки script вместо написания всех команд inline в Makefile нежелательна, но я буду использовать ее в качестве последнего средства.
по теме:
Ответы
Ответ 1
Я думаю, что вы ищете переменную оболочки $?
, которая дает код выхода предыдущей команды. Например:
$ 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
выполняются в разных процессах оболочки. Если вы хотите использовать статус вывода из команды, вы должны сделать это в контексте той же оболочки, что и в моем предыдущем примере.
Ответ 2
Используйте '$$?' вместо '$$!' (благодаря 4-му ответу Exit Shell Script на основе кода выхода процесса)
Ответ 3
Не забывайте, что каждая из ваших команд запускается в отдельных подоболочках.
Вот почему вы довольно часто видите что-то вроде:
my_target:
do something \
do something else \
do last thing.
И при отладке не забывайте каждую полезную опцию -n, которая будет печатать команды, но не выполнять их, и параметр -p, который покажет вам полную среду make, в том числе, где были установлены различные биты и куски.
НТН
веселит,
Ответ 4
Если вы передаете код результата в if
, вы можете просто сделать:
all:
if diff foo.txt foo.txt ; then echo "no differences" ; fi
Ответ 5
Переменная bash $?
, но почему вы все равно хотите распечатать код состояния?
Ответ 6
Попробуйте `\ $? ' Я думаю, что $$ интерпретируется makefile