Implementando execução a seco em scripts bash

15

Como alguém implementaria uma opção de execução a seco em um script bash?

Posso pensar em agrupar todos os comandos em um if e repetir o comando em vez de executá-lo se o script estiver sendo executado com dry-run.

Outra maneira seria definir uma função e, em seguida, passar cada chamada de comando por essa função.

Algo como:

function _run () {
    if [[ "$DRY_RUN" ]]; then
        echo $@
    else
        $@
    fi
}

`_run mv /tmp/file /tmp/file2`

`DRY_RUN=true _run mv /tmp/file /tmp/file2`

Isso está errado e há uma maneira muito melhor de fazê-lo?

Andrei Serdeliuc
fonte
Portanto, você deseja imprimir o que o comando fará (incluindo os valores de $ VARIABLES) sem realmente executar o comando. Uso algo como sua _run()função, às vezes com 'set -xv', mas adoraria uma maneira melhor.
Stefan Lasiewski
Sim, exatamente isso. Eu estou querendo saber se não há uma variável interna pode definir em bash tão comandos não realmente executar, em vez de passá-los através de uma função
Andrei Serdeliuc
2
Não há razão para que essa pergunta tenha sido marcada como wiki da comunidade.
Pausado até novo aviso.
Bash é uma concha. Não há razão para executar testes a seco. Eu não acho que exista uma maneira melhor de fazê-lo do que você já fez.
d -_- b

Respostas:

2

Veja BashFAQ / 050: Estou tentando colocar um comando em uma variável, mas os casos complexos sempre falham! para uma discussão sobre este assunto.

Embora agora removida, a seção Como adicionar capacidade de teste a um programa ainda pode ser útil.

Dennis Williamson
fonte
Não é uma alternativa, mas parece um excelente recurso para testar e trabalhar com programas bash mais longos.
Andrei Serdeliuc
Recuei a edição que adicionou uma âncora a uma parte específica da página vinculada, já que o ponto da minha resposta, como afirmado, é ler a discussão como um todo, em vez de apontar para uma parte específica de instruções. O objetivo da página vinculada geralmente é tentar evitar que comandos sejam executados em variáveis, pois existem muitas dicas.
Pausado até novo aviso.
Seria muito mais útil se essa resposta resumisse os pontos mais importantes deste artigo. As respostas de uma linha ainda são ruins.
Mark Booth
4

Eu queria brincar com a resposta de @Dennis Williamson's. Aqui está o que eu tenho:

Run () {
    if [ "$TEST" ]; then
        echo "$*"
        return 0
    fi

    eval "$@"
}

O eval "$@"é importante aqui, e é melhor do que simplesmente fazer $*. $@retorna todos os parâmetros e $*retorna todos os parâmetros sem espaços em branco / aspas.

$ mkdir dir
$ touch dir/file1 dir/file2
$ FOO="dir/*"
$ TEST=true Run ls -l $FOO
ls -l dir/file1 dir/file2
$ Run ls -l $FOO
-rw-r--r--  1 stefanl  stefanl  0 Jun  2 21:06 dir/file1
-rw-r--r--  1 stefanl  stefanl  0 Jun  2 21:06 dir/file2
Stefan Lasiewski
fonte