
Вот чего я пытаюсь добиться.
#!/bin/bash
safemode=on
if [ $safemode == 'off' ];then
run dangerous code
fi
У меня 129 опасных линий, которые все разделены. Как лучше всего это сделать?
решение1
«Лучший способ» сильно зависит от того, сколько усилий вы считаете максимальным. Один довольно простой способ — использовать &&
списки команд, связанные с -connected, для небольшой модификации вашего примера. Вы можете использовать либо конструкцию арифметического теста Bash:
#!/bin/bash
safemode=1
(( ! safemode )) && run dangerous code 1
uncritical code
(( ! safemode )) && run dangerous code 2
или обычный строковый оператор
#!/bin/bash
safemode=on
[[ $safemode = "off" ]] && run dangerous code 1
uncritical code
[[ $safemode = "off" ]] && run dangerous code 2
Это всего лишь довольно сокращенная запись того, что вы уже сделали: [[ ... ]]
тест выдаст результат false
if safemode
is not off
, следовательно, выполнение списка команд остановится на &&
.
Стоит отметить, что в случае &&
списка команд, связанных цепочкой, кодом завершения будет код последней выполненной команды, поэтому, если safemode
задано, то $?
будет 1
после таких «защищенных» строк (на всякий случай, если вы используете код завершения таким образом).
решение2
Если мы определим переменную safemode
как одну из двух команд true
или false
, то мы можем использовать это как префикс:
#!/bin/sh
safemode=true
safe_mode_off() { safemode=false }
"$safemode" || run dangerous code 1
uncritical code
"$safemode" || run dangerous code 2
Полагаю, мы обычно устанавливаем переменную в ходе обработки параметров, поэтому true
/ false
так же просто, как и on
/ off
.
Мымогвозможно, стоит расширить это (хотя я не думаю, что это обязательно нужно), чтобы просто сделать опасные команды аргументами false
, например так:
#!/bin/sh
risky=false
safe_mode_off() { risky= }
$risky run dangerous code 1
uncritical code
$risky run dangerous code 2
Однако в этом случае расширение все равно будет иметь место внутри аргументов — например, $(dangerous subcommand)
все равно будет выполнено, поэтому нам нужно изменить это на $($risky dangerous subcommand)
. Я думаю, что это слишком подвержено ошибкам для серьезного использования.
решение3
Если вам нужна стенография, вы можете использовать псевдоним. Они больше похожи на замену текста, чем на обычные расширения, поэтому синтаксические конструкцииможетбыть вставлены через них. Просто нужно явно включить в скриптах Bash, и вы хотите убедиться, что случайно не включили нежелательные псевдонимы.
#!/bin/bash
unalias -a
shopt -s expand_aliases
# default safe
alias risky='[ "$riskymode" = enabled ] &&'
riskymode=
if [ "$1" = risky ]; then
riskymode=enabled
fi
echo this is normal
risky echo this is risky
Но обратите внимание, что все еще есть оговорка, что условие по-прежнему является всего лишь частью -списка &&
, поэтому это:
risky echo try something risky || echo oopsie it failed
будет работать, echo oopsie
даже если riskymode отключен.
Но вы могли бы сделать:
risky ( echo try something risky || echo oopsie it failed )
или даже
risky if ! echo another risky attempt; then echo another failure; fi
(вы можете поместить составную команду внутрь &&
списка)
Мы даже могли бы сделать строку комментарием с помощью псевдонима:
#!/bin/bash
unalias -a
shopt -s expand_aliases
alias risky='#'
if [ "$1" = risky ]; then
alias risky=''
fi
risky echo something risky, again || echo "does it fail now?"
но тогда, конечно, он просто проигнорирует первыйлиния, поэтому это снова запустит вторую строку в «безопасном» режиме:
risky echo something even more risky ||
echo "_now_ does it fail?"