2 votos

Condicionalmente, ejecute un bloque de comando con BASH heredoc

Quería tener algo tan simple como que en mi script:

set_dryrun()
{
    BEGIN='cat << EOF'
    END='EOF'
}

[ "$1" == "-dryrun" ] && set_dryrun

${BEGIN}
    ls -l
${END}

Así que si me quedo es con la -dryrun parámetro, los comandos entre ${BEGIN} y ${END} sería acaba de imprimir, pero no se ejecutan.

Todo va bien si me quedo sin el -dryrun flag:

$ ./dryrun_opt 
-rwxrwxr-x 1 arantesj arantesj 160 jan 25 17:15 dryrun_opt

Con -dryrun, sin embargo, voy a ver:

$ ./dryrun_opt -dryrun
cat: '<<': No such file or directory
cat: EOF: No such file or directory
-rwxrwxr-x 1 arantesj arantesj 160 jan 25 17:16 dryrun_opt
./dryrun_opt: line 14: EOF: command not found

Bueno... yo no soy la sustitución (en expansión?) mi heredoc correctamente, lo sé, pero, ¿cómo debería, si es posible?

Gracias de antemano.

1voto

Jim L. Puntos 66

Esto funciona para mí:

set_dryrun()
{
    BEGIN='cat << EOF'
    END='EOF'
}

[ "$1" == "-dryrun" ] && set_dryrun

eval "${BEGIN}
    ls -l
${END}"

Sospecho, sin embargo, que este enfoque va a romper en algún momento, cuando el heredoc se vuelve más complejo de lo que 'ls -l'. Si no se citando o escapar pasando en el interior que tendría que hacerse con cuidado o un enfoque de este sencillo es probable que se rompa.

El endeudamiento de la sabiduría de este Stack Overflow del subproceso, usted puede encontrar este enfoque interesante a tener en cuenta:

if [ "$1" == "-dryrun" ]
then
        CMD="cat"
else
        CMD="bash"      # your preferred shell here
fi

WORK="$(cat <<'EOF'
# abc'asdf"
# $(dont-execute-this)
# foo"bar"''
ls -l
echo "$PATH"
echo "\$PATH"
EOF
)"

$CMD <<< "$WORK"

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: