На сделать версию 4.2 {2016} была добавлена переменная .SHELLSTATUS
. Но мой самый linux использует make version 4.1
. Как я могу получить статус выхода и результаты вывода команды make $ (shell ...) в старых версиях make?
С make 4.2 я могу сделать это:
newmake:
printf '%s\n' "$(shell command && \
( printf 'Successfully created the zip file!\n'; exit 0 ) || \
( printf 'Error: Could not create the zip file!\n'; exit 1 ) )"
printf 'Exit status: '%s'\n' "${.SHELLSTATUS}"
Который работает правильно:
printf '%s\n' "Successfully created the zip file!"
Successfully created the zip file!
printf 'Exit status: '%s'\n' "0"
Exit status: 0
Но, если я использую make 4.1 или старше, переменная .SHELLSTATUS
отсутствует. Затем я пытаюсь определить свою собственную переменную .SHELLSTATUS
следующим образом:
oldmake:
printf '%s\n' "$(shell command && \
( printf 'Successfully created the zip file!\n'; $(eval exit_status := 0) echo ${exit_status} > /dev/null ) || \
( printf 'Error: Could not create the zip file!\n'; $(eval exit_status := 1) echo ${exit_status} > /dev/null ) )"
printf 'Exit status: '%s'\n' "${exit_status}"
Но он работает неправильно:
printf '%s\n' "Successfully created the zip file!"
Successfully created the zip file!
printf 'Exit status: '%s'\n' "1"
Exit status: 1
Как видите, правильное сообщение было напечатано, но статус выхода должен быть 0
, а не 1
.
Примечание
Сообщения Successfully created the zip file!
и Error: Could not create the zip file!
являются исключительно иллюстративными и не могут использоваться за пределами $(shell ...)
. Что у меня внутри оболочки, так это полнофункциональный Python
скрипт, который выводит свои результаты на экран:
define NEWLINE
endef
define RELEASE_CODE
from __future__ import print_function
import os
import zipfile
version = "${version}"
if not version:
print( "Error: You need pass the release version. For example: make release version=1.1", end="@NEWNEWLINE@" )
exit(1)
CURRENT_DIRECTORY = os.path.dirname( os.path.realpath( __file__ ) )
print( "Packing files on %s" % CURRENT_DIRECTORY, end="@NEWNEWLINE@" )
file_names = []
initial_file_names = [
"Makefile",
"build.bat",
"fc-portuges.def",
os.path.join("setup", "makefile.mk"),
os.path.join("setup", "scripts", "timer_calculator.sh"),
]
for direcory_name, dirs, files in os.walk(CURRENT_DIRECTORY):
if ".git" in direcory_name:
continue
for filename in files:
filepath = os.path.join( direcory_name, filename )
if ".git" in filepath or not ( filepath.endswith( ".tex" )
or filepath.endswith( ".bib" )
or filepath.endswith( ".pdf" ) ):
continue
file_names.append( filepath )
for filename in initial_file_names:
filepath = os.path.join( CURRENT_DIRECTORY, filename )
file_names.append( filepath )
zipfilepath = os.path.join( CURRENT_DIRECTORY, version + ".zip" )
zipfileobject = zipfile.ZipFile(zipfilepath, mode="w")
zipfilepathreduced = os.path.dirname( os.path.dirname( zipfilepath ) )
try:
for filename in file_names:
relative_filename = filename.replace( zipfilepathreduced, "" )
print( relative_filename, end="@NEWNEWLINE@" )
zipfileobject.write( filename, relative_filename, compress_type=zipfile.ZIP_DEFLATED )
except Exception as error:
print( "", end="@NEWNEWLINE@" )
print( "An error occurred: %s" % error, end="@NEWNEWLINE@" )
exit(1)
finally:
zipfileobject.close()
print( "", end="@NEWNEWLINE@" )
print( "Successfully created the release version on:@NEWNEWLINE@ %s!" % zipfilepath , end="" )
endef
all:
printf '%s\n' "$(shell echo \
'$(subst ${NEWLINE},@NEWLINE@,${RELEASE_CODE})' | \
sed 's/@NEWLINE@/\n/g' | python - && \
printf 'Successfully created the zip file!\n' || \
printf 'Error: Could not create the zip file!\n' )" | sed 's/@NEWNEWLINE@/\n/g'
Теперь он работает правильно, но мне не хватает кода выхода Python, который можно исправить с помощью этого .SHELLSTATUS
:
all:
printf '%s\n' "$(shell echo \
'$(subst ${NEWLINE},@NEWLINE@,${RELEASE_CODE})' | \
sed 's/@NEWLINE@/\n/g' | python - && \
( printf 'Successfully created the zip file!\n'; exit 0 ) || \
( printf 'Error: Could not create the zip file!\n'; exit 1 ) )" | sed 's/@NEWNEWLINE@/\n/g'
exit "${.SHELLSTATUS}"
Но это работает только для версии make 4.2
или новее.
Связанный:
- https://askubuntu.com/questions/93499/assign-standard-exit-status-to-a-makefile-variable
- Возвращение значения из вызываемой функции в сценарии оболочки
- Как получить статус завершения команды оболочки, используемой в Makefile GNU?
- Как заставить GNU сделать сбой, если команда оболочки, назначенная переменной, не удалась?
- Коды состояния оболочки в марке
- Создать zip-архив с несколькими файлами
- Zip Несколько файлов с несколькими результатами в Python
- python / zip: Как исключить абсолютный путь в zip-архиве, если указаны абсолютные пути для файлов?
- Как отправить входные данные на стандартный ввод скрипту Python, определенному в Makefile?