Comentarios condicionales para shell peligroso

Comentarios condicionales para shell peligroso

Esto es lo que estoy tratando de lograr.

#!/bin/bash
safemode=on

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

Tengo 129 líneas peligrosas que están todas separadas. ¿Cuál es la mejor manera de hacer esto?

Respuesta1

La "mejor manera" depende en gran medida de cuánto esfuerzo consideres máximo. Una forma bastante sencilla es utilizar &&listas de comandos conectadas para realizar una ligera modificación de su ejemplo. Puede utilizar cualquiera de las dos construcciones de prueba aritmética de Bash:

#!/bin/bash
safemode=1

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

o el operador normal basado en cadenas

#!/bin/bash
safemode=on

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

Esto es simplemente una notación bastante breve de lo que ya hizo: la [[ ... ]]prueba dará resultados falsesi safemodeno es off, por lo tanto, la ejecución de la lista de comandos se detendrá en &&.

Podría valer la pena señalar que en el caso de una &&lista de comandos encadenados, el código de salida será el del último comando ejecutado, por lo que si safemodeestá configurado, $?estará 1después de dichas líneas "protegidas" (en caso de que use el código de salida de ese modo).

Respuesta2

Si definimos una variable safemodecomo uno de los dos comandos trueo false, entonces podemos usarlo como prefijo:

#!/bin/sh
safemode=true

safe_mode_off() { safemode=false }

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

Supongo que normalmente estableceríamos la variable desde nuestro procesamiento de opciones, por lo que true/ falsees tan fácil como on/ off.


Nosotrospodríatal vez extender esto (aunque no necesariamente creo que debamos hacerlo) para hacer que los comandos peligrosos se conviertan en argumentos false, como este:

#!/bin/sh
risky=false

safe_mode_off() { risky= }

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

Sin embargo, en este caso, la expansión seguirá teniendo lugar dentro de los argumentos; por ejemplo, $(dangerous subcommand)aún se ejecutará, por lo que necesitaremos cambiar eso a $($risky dangerous subcommand). Creo que es demasiado propenso a errores para un uso serio.

Respuesta3

Si desea una abreviatura, puede utilizar un alias. Se parecen más a un reemplazo de texto que a cualquier expansión normal, por lo que las construcciones de sintaxispoderinsertarse a través de ellos. Solo necesita habilitarlo explícitamente en los scripts Bash y asegurarse de no habilitar accidentalmente también los alias no deseados.

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

Pero tenga en cuenta que todavía existe la advertencia de que la condición sigue siendo solo parte de una &&lista, por lo que esto:

risky echo try something risky || echo oopsie it failed

ejecutaría echo oopsieincluso si el modo riesgo está deshabilitado.

Pero podrías hacer:

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

o incluso

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

(puedes poner un comando compuesto dentro de una &&lista)


Incluso podríamos hacer que el alias convierta la línea en un comentario:

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

pero luego, por supuesto, simplemente ignorará el primero.línea, por lo que esto ejecutaría nuevamente la segunda línea en modo "seguro":

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

información relacionada