bash — как обработать код выхода при использовании set -e и получить вывод команды

#bash

#bash

Вопрос:

У меня есть set -e в верхней части скрипта. Как избежать завершения скрипта для некоторых команд и обработать код выхода? У меня возникли трудности со следующим примером кода:
мне нужны как вывод в переменную, так и код выхода, без set -e этого просто.

 set -e
...
formoutput=$(yad --form --field="Subdomain" --field="Domain" --field="Web master username" 
  --field="Apache group" --field='Webroot' 
  --field='Webroot variables - ${homedir}(of webmaster) ${subdomain} ${webmaster} ${domain}:LBL' 
  --field="Virtualhost ip or domain" 
  --field="Virtualhost port" --field="Server admin email" 
  --field="Create mysql useramp;db:CHK" 
  --button="Cancel:3" --button="Save defaults:2" --button="Create:0" 
  --title="Create apache virtualhost" 
  --text='Subdomain are case sencetive for Webroot folder ${subdomain} variable' 
  --focus-field=1 --center --window-icon="preferences-system" --width=600 
  "${config[subdomain]}" "${config[domain]}" "${config[webmaster]}" "${config[webgroup]}" 
  "${config[webroot]}" "test" "${config[virtualhost]}" "${config[virtualport]}" "${config[serveradmin]}" 1)
formbutton="$?"
  

Ответ №1:

Мне нужно было использовать операторы в другом порядке, чтобы это сработало

 $ set -e
$ true || status=$? amp;amp; status=$?; echo $status
0
$ false || status=$? amp;amp; status=$?; echo $status
0
$ true amp;amp; status=$? || status=$?; echo $status
0
$ false amp;amp; status=$? || status=$?; echo $status
1
  

Комментарии:

1. Интересно, ответ на самом деле неправильный, amp;amp; должен быть первым.

2. Да, кажется, правильный ответ с amp;amp; первым: command amp;amp; status=$? || status=$?

Ответ №2:

Вам нужно обработать код выхода команды.

Статус выхода команды — это статус выхода последней выполненной команды.

Присвоение переменной не является командой.

Таким образом, вы можете просто делать то, что популярно в set -e скриптах:

 formoutput=$(yad ...) || ret=$? amp;amp; ret=$?
  

чтобы перехватить возвращаемое значение.

Или вы можете проигнорировать выход, вызвав : команду:

 formoutput=$(yad ...) ||:
  

||: На самом деле это || с : помощью command. Команда двоеточия возвращает нулевой статус выхода, статус выхода списка команд a || b — это статус выхода последней команды, выполненной в списке, поскольку : всегда возвращает ноль, список команд также вернет нулевой статус выхода.

Или использовать if :

 if ! formoutput=$(yad ...); then 
          echo "AAAA! yad failed! abort ship!" >amp;2
fi
  

Обратите внимание, что if команда также имеет статус выхода последней выполненной команды. Поэтому имейте в виду, что:

 if true; then
    false
fi
  

завершится из вашего set -e скрипта.

Комментарии:

1.С if ! cmd $? всегда 0 . Я предпочитаю if cmd ; then :; else rc=$? ; fi

Ответ №3:

Попробуйте это:

 set -e
false || echo $? amp;amp; echo 0
  

Даже если false завершается с 1, вы сможете зафиксировать это значение выхода в середине (с $? ) без прерывания всего сценария.

Если скрипт ( false ) не завершился сбоем, код выхода всегда равен нулю, поэтому вы можете просто поставить ноль при успешном выполнении.

Комментарии:

1. Это то, как я делаю для других команд, не приведенных в примере кода. Проблема с захватом вывода команды и кода выхода, обоих.

2. ? это просто formoutput=$(....) || echo $? amp;amp; echo 0 Статус выхода выражения — это статус возврата последней выполненной команды. Назначение переменной не является выполнением команды. Таким образом, статус выхода formoutput=$(bla) будет статусом выхода команды bla . И вы можете нормально связать его. if a=$(true); then echo 1; else echo 2; fi

3. @KamilCuk Спасибо. Я застрял, пытаясь использовать аналогичный, но внутри ()