GNU Make не игнорирует неудачную команду

Аннотация

Чтобы отменить set -x , просто выполните set + x . В большинстве случаев обратная строка set -str совпадает с строкой + : set + str .

В общем, чтобы восстановить все (читайте ниже о bash errexit ) параметры оболочки (измененные с помощью команды set ), вы можете сделать это (также читайте ниже о bash shopt ):

oldstate="$(set +o); set -$-"                # POSIXly store all set options.
.
.
set -vx; eval "$oldstate"         # restore all options stored.

Более длинное описание

bash

Эта команда:

shopt -po xtrace

сгенерирует исполняемую строку, отражающую состояние параметра. Флаг p означает печать, а флаг o указывает, что мы спрашиваем об опциях, установленных командой set (в отличие от опций, установленных командой shopt ). Вы можете присвоить эту строку переменной и выполнить ее в конце сценария, чтобы восстановить исходное состояние.

# store state of xtrace option.
tracestate="$(shopt -po xtrace)"

# change xtrace as needed
echo "some commands with xtrace as externally selected"
set -x
echo "some commands with xtrace set"

# restore the value of xtrace to its original value.
eval "$tracestate"

Это решение работает для нескольких параметров одновременно:

oldstate="$(shopt -po xtrace noglob errexit)"

# change options as needed
set -x
set +x
set -f
set -e
set -x

# restore to recorded state:
set +vx; eval "$oldstate"

Добавление set + vx позволяет избежать печати длинного списка параметров.


И, если вы не укажете никаких названий опций,

oldstate="$(shopt -po)"

покажет вам значения всех опций. И, если вы опустите флаг o , вы можете сделать то же самое с параметрами shopt :

# store state of dotglob option.
dglobstate="$(shopt -p dotglob)"

# store state of all options.
oldstate="$(shopt -p)"

Если вам нужно протестировать установлен ли параметр set , наиболее идиоматичный (Bash) способ сделать это:

[[ -o xtrace ]]

что лучше, чем два других аналогичных теста:

{{1} }

  1. [[$ - = ~ x]]
  2. [[$ - == * x *]]

С любым из тестов это работает:

# record the state of the xtrace option in ts (tracestate):
[ -o xtrace ] && ts='set -x' || ts='set +x'

# change xtrace as needed
echo "some commands with xtrace as externally selected"
set -x
echo "some commands with xtrace set"

# set the xtrace option back to what it was.
eval "$ts"

Вот как проверить состояние опции shopt :

if shopt -q dotglob
then
        # dotglob is set, so “echo .* *” would list the dot files twice.
        echo *
else
        # dotglob is not set.  Warning: the below will list “.” and “..”.
        echo .* *
fi

POSIX

Простой, POSIX -совместимое решение для хранения всех параметров набора :

set +o

, который описан в стандарте POSIX как:

+ o

    Записать текущие настройки параметров в стандартный вывод в формате , который подходит для повторного ввода в оболочку в качестве команд, которые достигают тех же настроек параметров.

Итак, просто:

oldstate=$(set +o)

сохранит значения для всех параметров, установленных с помощью команды set .

Опять же, восстановление параметров до их исходных значений - это вопрос выполнения переменной:

set +vx; eval "$oldstate"

Это в точности эквивалентно использованию Bash shopt -po . Обратите внимание, что он не охватывает все возможные Bash параметры, поскольку некоторые из них устанавливаются shopt .

Особый случай bash

Есть много других параметров оболочки, перечисленных в shopt в bash:

$ shopt
autocd          off
cdable_vars     off
cdspell         off
checkhash       off
checkjobs       off
checkwinsize    on
cmdhist         on
compat31        off
compat32        off
compat40        off
compat41        off
compat42        off
compat43        off
complete_fullquote  on
direxpand       off
dirspell        off
dotglob         off
execfail        off
expand_aliases  on
extdebug        off
extglob         off
extquote        on
failglob        off
force_fignore   on
globasciiranges off
globstar        on
gnu_errfmt      off
histappend      on
histreedit      off
histverify      on
hostcomplete    on
huponexit       off
inherit_errexit off
interactive_comments    on
lastpipe        on
lithist         off
login_shell     off
mailwarn        off
no_empty_cmd_completion off
nocaseglob      off
nocasematch     off
nullglob        off
progcomp        on
promptvars      on
restricted_shell    off
shift_verbose   off
sourcepath      on
xpg_echo        off

Их можно добавить к переменной, указанной выше, и восстановить таким же образом:

$ oldstate="$oldstate;$(shopt -p)"
.
.                                   # change options as needed.
.
$ eval "$oldstate" 

Это можно сделать ( $ - добавляется, чтобы гарантировать сохранение errexit ):

oldstate="$(shopt -po; shopt -p); set -$-"

set +vx; eval "$oldstate"             # use to restore all options.

Примечание : каждая оболочка имеет немного другой способ построения списка опций которые установлены или не установлены (не говоря уже о различных опциях, которые определены), поэтому строки не переносятся между оболочками, но действительны для одной и той же оболочки.

Особый случай zsh

zsh также работает правильно (в соответствии с POSIX), начиная с версии 5.3. В предыдущих версиях он следовал POSIX лишь частично с set + o в том смысле, что он печатал параметры в формате, подходящем для повторного ввода в оболочку в виде команд, но только для set options (it не печатал снятые параметры).

Особый случай mksh

mksh (и, как следствие, lksh) еще не может (MIRBSD KSH R54 2016/11/11) сделать это. В руководстве по mksh содержится следующее:

В будущей версии set + o будет вести себя в соответствии с POSIX, а команды печати вместо этого будут восстанавливать текущие параметры.

set -e специальный случай

В bash значение set -e ( errexit ) сбрасывается внутри суб-оболочки, что затрудняет захват его значения. с set + o внутри суб-оболочки $ (…).

В качестве временного решения используйте:

oldstate="$(set +o); set -$-"
3
28.06.2015, 19:10
0 ответов

Теги

Похожие вопросы