Bedingtes Kommentieren für gefährliche Shell

Bedingtes Kommentieren für gefährliche Shell

Folgendes versuche ich zu erreichen:

#!/bin/bash
safemode=on

if [ $safemode == 'off' ];then
  run dangerous code
fi

Ich habe 129 gefährliche Zeilen, die alle getrennt sind. Wie gehe ich dabei am besten vor?

Antwort1

„Bester Weg“ hängt stark davon ab, wie viel Aufwand Sie als maximal erachten. Eine recht einfache Möglichkeit besteht darin, &&-verbundene Befehlslisten für eine leichte Modifikation Ihres Beispiels zu verwenden. Sie können entweder die arithmetische Testkonstruktion von Bash verwenden:

#!/bin/bash
safemode=1

(( ! safemode )) && run dangerous code 1
uncritical code
(( ! safemode )) && run dangerous code 2

oder der normale stringbasierte Operator

#!/bin/bash
safemode=on

[[ $safemode = "off" ]] && run dangerous code 1
uncritical code
[[ $safemode = "off" ]] && run dangerous code 2

Dies ist lediglich eine Kurznotation für das, was Sie bereits getan haben: Der [[ ... ]]Test ergibt ein Ergebnis, falsewenn safemodenicht ist off, daher wird die Ausführung der Befehlsliste bei beendet &&.

Es ist möglicherweise erwähnenswert, dass im Fall einer &&verketteten Befehlsliste der Exit-Code der des zuletzt ausgeführten Befehls ist. Wenn also safemodegesetzt ist, $?steht dies 1nach solchen „geschützten“ Zeilen (nur für den Fall, dass Sie den Exit-Code auf diese Weise verwenden).

Antwort2

Wenn wir eine Variable safemodeals einen der beiden Befehle trueoder definieren false, können wir das als Präfix verwenden:

#!/bin/sh
safemode=true

safe_mode_off() { safemode=false }

"$safemode" || run dangerous code 1
uncritical code
"$safemode" || run dangerous code 2

Ich schätze, wir würden die Variable normalerweise über unsere Optionenverarbeitung festlegen, daher ist true/ falseso einfach wie on/ off.


WirkönnteVielleicht könnten wir dies erweitern (obwohl ich nicht unbedingt denke, dass wir das tun sollten), indem wir einfach die gefährlichen Befehle zu Argumenten für machen false, etwa so:

#!/bin/sh
risky=false

safe_mode_off() { risky= }

$risky run dangerous code 1
uncritical code
$risky run dangerous code 2

In diesem Fall findet die Erweiterung jedoch weiterhin innerhalb der Argumente statt – zB $(dangerous subcommand)würde weiterhin ausgeführt, daher müssten wir das in ändern $($risky dangerous subcommand). Ich denke, das ist für eine ernsthafte Verwendung zu fehleranfällig.

Antwort3

Wenn Sie eine Abkürzung möchten, können Sie einen Alias ​​verwenden. Sie ähneln eher einem Textersatz als einer regulären Erweiterung, sodass Syntaxkonstruktedürfendurch sie eingefügt werden. Sie müssen es nur explizit in Bash-Skripten aktivieren und Sie möchten sicherstellen, dass Sie nicht versehentlich auch unerwünschte Aliase aktivieren.

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

Beachten Sie jedoch, dass weiterhin der Vorbehalt besteht, dass die Bedingung nur Teil einer &&-Liste ist, also Folgendes:

risky echo try something risky || echo oopsie it failed

würde ausgeführt werden, echo oopsieauch wenn der Risikomodus deaktiviert ist.

Aber Sie könnten Folgendes tun:

risky ( echo try something risky || echo oopsie it failed )

oder auch

risky if ! echo another risky attempt; then echo another failure; fi

(Sie können einen zusammengesetzten Befehl in eine &&-Liste einfügen)


Wir könnten den Alias ​​sogar so einrichten, dass die Zeile ein Kommentar wird:

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

aber dann ignoriert es natürlich einfach die ersteLinie, daher würde die zweite Zeile erneut im „abgesicherten“ Modus ausgeführt:

risky echo something even more risky ||
    echo "_now_ does it fail?"

verwandte Informationen