Ответ 1
Тело функции может быть любой составной командой, а не только командой группы ({}
). Используйте под-оболочку:
is_hello_world() (
shopt -s nocasematch
[[ "$1" =~ "hello world" ]]
)
Я пытаюсь написать функцию bash, которая использует nocasematch
не изменяя настройку вызывающих опций. Определение функции:
is_hello_world() {
shopt -s nocasematch
[[ "$1" =~ "hello world" ]]
}
Прежде чем я позвоню:
$ shopt nocasematch
nocasematch off
Назови это:
$ is_hello_world 'hello world' && echo Yes
Yes
$ is_hello_world 'Hello World' && echo Yes
Yes
Как и ожидалось, но теперь nocasematch
абонента изменилось:
$ shopt nocasematch
nocasematch on
Есть ли какой-либо простой способ изменить параметр на локальную функцию?
Я знаю, что могу проверить возвращаемое значение shopt -q
но это все равно означает, что функция должна запомнить это и сбросить его перед выходом.
Тело функции может быть любой составной командой, а не только командой группы ({}
). Используйте под-оболочку:
is_hello_world() (
shopt -s nocasematch
[[ "$1" =~ "hello world" ]]
)
Я знаю эту дату публикации с 2012 года, но вы также можете сделать следующее (работает в Git Bash 1.8.4 на Windows, поэтому он должен работать на Linux):
function foobar() {
local old=$(shopt -p extglob)
shopt -s extglob
... your stuff here ...
eval "$old"
}
Опция -p
просто печатает shopt -s extglob
если extglob
, иначе shopt -u extglob
.
shopt -p
распечатает весь список опций.
Команды, заданные с помощью ловушки RETURN, выполняются до того, как выполнение возобновится после того, как функция оболочки... возвращает...
Параметр
-p
[to shopt] вызывает вывод вывода в форме, которая может быть повторно использована в качестве входных данных.
foobar() {
trap "$(shopt -p extglob)" RETURN
shopt -s extglob
# ... your stuff here ...
}
Для теста
foobar() {
trap "$(shopt -p extglob)" RETURN
shopt -s extglob
echo "inside foobar"
shopt extglob # Display current setting for errexit option
}
main() {
echo "inside main"
shopt extglob # Display current setting for errexit option
foobar
echo "back inside main"
shopt extglob # Display current setting for errexit option
}
Контрольная работа
$ main
inside main
extglob off
inside foobar
extglob on
back inside main
extglob off
Вариация: Чтобы сбросить все параметры магазина, измените оператор ловушки на:
trap "$(shopt -p)" RETURN
Вариация: Чтобы сбросить все параметры набора, измените оператор ловушки на:
trap "$(set +o)" RETURN
Примечание. Начиная с Bash 4.4, есть лучший способ: make $ - local.
Вариация: Чтобы сбросить все настройки и все параметры магазина, измените оператор ловушки на:
trap "$(set +o)$(shopt -p)" RETURN
ПРИМЕЧАНИЕ: set +o
эквивалентен shopt -p -o
:
+o Запишите текущие настройки параметров на стандартный вывод в формате, подходящем для повторного включения в оболочку, в качестве команд, которые выполняют те же настройки параметров.
- Открытые базовые спецификации группы Издание 7, 2018 издание> установлено
Вы можете использовать ассоциативный массив, чтобы запомнить предыдущий параметр, а затем использовать его для возврата к предыдущему параметру, например так:
declare -gA _shopt_restore
shopt_set() {
local opt count
for opt; do
if ! shopt -q "$opt"; then
echo "$opt not set, setting it"
shopt -s "$opt"
_shopt_restore[$opt]=1
((count++))
else
echo "$opt set already"
fi
done
}
shopt_unset() {
local opt restore_type
for opt; do
restore_type=${_shopt_restore[$opt]}
if shopt -q "$opt"; then
echo "$opt set, unsetting it"
shopt -u "$opt"
_shopt_restore[$opt]=2
else
echo "$opt unset already"
fi
if [[ $restore_type == 1 ]]; then
unset _shopt_restore[$opt]
fi
done
}
shopt_restore() {
local opt opts restore_type
if (($# > 0)); then
opts=("[email protected]")
else
opts=("${!_shopt_restore[@]}")
fi
for opt in "${opts[@]}"; do
restore_type=${_shopt_restore[$opt]}
case $restore_type in
1)
echo "unsetting $opt"
shopt -u "$opt"
unset _shopt_restore[$opt]
;;
2)
echo "setting $opt"
shopt -s "$opt"
unset _shopt_restore[$opt]
;;
*)
echo "$opt wasn't changed earlier"
;;
esac
done
}
Затем используйте эти функции как:
... some logic ...
shopt_set nullglob globstar # set one or more shopt options
... logic that depends on the above shopt settings
shopt_restore nullglob globstar # we are done, revert back to earlier setting
или же
... some logic ...
shopt_set nullglob
... some more logic ...
shopt_set globstar
... some more logic involving shopt_set and shopt_unset ...
shopt_restore # restore everything
Полный исходный код здесь: https://github.com/codeforester/base/blob/master/lib/shopt.sh