Условное комментирование для опасной оболочки

Условное комментирование для опасной оболочки

Вот чего я пытаюсь добиться.

#!/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

Это всего лишь довольно сокращенная запись того, что вы уже сделали: [[ ... ]]тест выдаст результат falseif safemodeis 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?"

Связанный контент