Совместимость скриптов: Сохранить $? для использования позже

Я хотел бы написать небольшую часть скрипта, который сохраняет статус ошибки, выполняет другой код и устанавливает статус ошибки в исходный статус ошибки. В Bash это выглядит так:

<< some command >>; _EXIT=$?;( <<other code here>> ;exit $_EXIT) 

Но мне нужен код, который будет работать независимо от того, выполняется ли он под bash, zsh, csh или tcsh. Я не знаю, какая оболочка будет использоваться заранее, потому что она определяется пользователем. Пользователь также решает << некоторая команда >>.

Можно с уверенностью предположить, что << other code >> будет работать во всех оболочках, но небезопасно предполагать, что вы можете записать файл (поэтому его включение в файл не будет работать).

Задний план

GNU Parallel выполняет команды, заданные пользователем в оболочке, принятой пользователем. Когда команда завершена, GNU Parallel выполняет некоторую очистку. В то же время GNU Parallel должна запоминать значение выхода команды, заданной пользователем. Код, выполняемый перед приведенным выше фрагментом, является заданной пользователем командой. << другой код >> – это код очистки.

2 Solutions collect form web for “Совместимость скриптов: Сохранить $? для использования позже”

Этот ответ работает в bash-подобных оболочках и csh-подобных оболочках, и для него не требуется perl:

 sh -c '<< other code >>; [ "$0" != "" ] && exit "$0"; exit "$1"' "$?" "$status" 

или вы можете добавить параметр фиктивного / пэда:

 sh -c '<< other code >>; [ "$1" != "" ] && exit "$1"; exit "$2"' foo "$?" "$status" 

и тест можно изменить на [ ! -z "$0" ] [ ! -z "$0" ] (или "$1" ). Я не знаю, будет ли это работать в zsh или рыбе. Каждая оболочка, с которой я знаком, будет оценивать $? и $status когда команда разобрана, и передайте их команде sh -c качестве параметров. Оболочка sh присваивает их двум последним позиционным параметрам. Когда «другой код» заканчивается, оболочка проверяет параметр позиционирования, который получил свое значение от $? чтобы определить, является ли он нулевым или ненулевым, и выйдите с соответствующим значением позиционного параметра.

Это не сработает, если окружающая оболочка использует нечто, отличное от $? или $status чтобы сохранить статус выхода. Он также потерпит неудачу, если оболочка разрешит $? (не нуль), если это не статус выхода, или $? является недопустимой последовательностью символов, которая заставляет всю команду отклоняться как синтаксическую ошибку.

Использовать perl:

 perl -e '$a=shift; `<< other code >>`; exit $a' $? # Fails in csh 

Редактировать Это работает и в csh (и zsh, tcsh, sh, pdksh, ksh93 – хотя и не рыба):

 perl -e '$a=shift; `<< other code >>`; $a=~s/h// and exit $a; exit shift' "$?h" "$status" 
  • zsh !! и! $ auto выполняется так же, как и в bash
  • Определить сеанс tmux, к которому относится сеанс оболочки?
  • Как я могу достичь root после переключения с bash на zsh?
  • Livesearch с первыми 10 матчами в качестве предварительного просмотра для zsh-history?
  • Различия в перенаправлении между &>> & и 2> & 1
  • «Gnome-terminal -e tmux ./» постоянно открывает терминалы
  • Захват имени файла, указанного символической ссылкой в ​​переменной
  • Существуют ли проблемы с дефисами в функциях, псевдонимах и исполняемых файлах?
  • Использование псевдонима zsh для быстрого клонирования репозитория git с именем пользовательской папки
  • Экспорт истории команд в скрипт командной оболочки
  • dnf установить завершение не работает с zsh, но работает с bash
  • Interesting Posts

    Прочтите Apple nvram

    Некоторые символы мусора в терминале Linux

    Индекс Mutt, исчезающий при повторном подключении IMAP

    Значки национальных флагов

    Как установить поле linux для получения сообщений электронной почты с использованием моего адреса электронной почты

    Устранение URL-адресов на сервере

    Mount unionfs (или aufs) ветвей, поданных из stdin?

    Как конвертировать скрипт init Ubuntu в сценарий инициализации Amazon Linux AMI?

    Почему я должен использовать sh для выполнения сценариев с CD / DVD-носителей?

    обмен полями в столбцах по фиксированной схеме (да, нет, нет, да)

    Исправить разрешения CIFS: файлы, созданные через Windows, имеют 777 разрешений для Linux

    Вставка текста между двумя шаблонами

    Git alias multi-commands с; а также &&

    Правильный подход для обновления apt-программного обеспечения до не-подходящих версий?

    Извлечь файлы с определенным расширением файла и сохранить структуру каталогов?

    Linux и Unix - лучшая ОС в мире.