Como fazer o eco dos comandos em um script de shell bash, mas não executá-los?

9

Existe uma maneira de executar um script de shell com os comandos mas sem realmente executá-los?

Digamos que eu tenha um script removendo um arquivo cujo nome está armazenado em uma variável:

#!/bin/bash
set -v
FN="filename"
rm -f ${FN}

Adicionar set -v ecoará os seguintes comandos antes da execução:

$ ./scr.sh
FN="filename"
rm -f ${FN}

Agora, quero ver o fluxo desse script sem realmente remover o arquivo. IOW, eu quero evitar qualquer efeito no ambiente externo e no sistema de arquivos. Isso é possível?

Eu poderia agrupar todos os comandos com um comando echo , mas é cansativo para um longo script.

    
por ysap 16.01.2013 / 20:43

7 respostas

7

Não há como passar por um script para ver como ele seria executado sem realmente fazer isso. No seu exemplo, não há if declarações ou loops. Mas em scripts reais, muitas vezes há muitas declarações condicionais. Qual ramificação será usada dependerá do que aconteceu quando o shell executou o comando anterior. Se não executar o comando, não há como o shell saber qual saída ele teria gerado ou qual seria o código de retorno, em que a próxima instrução condicional ou atribuição dependeria.

Se o ponto é que você gostaria de examinar um roteiro e saber o que ele faz antes de executá-lo, não é uma má ideia. Mas, de forma realista, a melhor maneira de fazer isso é simplesmente navegar no arquivo com less ou vi ou algo semelhante.

Adicionado

Se você estiver desenvolvendo um script e quiser percorrê-lo pela primeira vez, testando a lógica, mas sem causar nenhum dano se tiver um bug, a solução que geralmente consigo usar é para modificar apenas as declarações que poderiam causar algum dano colando um echo na frente.

Isso geralmente funciona em scripts típicos da vida real porque (a) gerar as listas de itens que você vai iterar ou o valor para o qual você configurará uma variável pode ser gerado sem alterar o sistema de arquivos e (b) é geralmente suficiente para assumir que, se você executasse o comando, ele seria bem-sucedido.

    
por 16.01.2013 / 20:52
6

Acho que você terá que fazer eco - no entanto, se você colocar o comando em uma variável, poderá ativá-lo e desativá-lo. Além disso, o comando pode ser uma função e tão sofisticado quanto você quiser. %pr_e%

%pr_e%

ao vivo -rw-rw-r-- 1 ninguém ninguém 0 2013-01-18 15:28 testy ls: não pode acessar testy: Nenhum arquivo ou diretório

    
por 18.01.2013 / 16:42
4

Você rastreia o fluxo usando a opção -x para o bash, mas isso ainda executaria os comandos.

O melhor que você pode fazer é apenas colocar echo ou comentar os comandos que possuem efeitos externos como o rm. Pelo menos você não teria que mudar todas as linhas.

    
por 16.01.2013 / 20:55
2

Execute set –n ou anexe n ao seu comando set –v existente. Mas como isso faz com que o shell não avalie nenhum comando, nem mesmo if ou while , talvez você não tenha uma visão muito boa do fluxo operacional.

    
por 16.01.2013 / 20:53
2

Eu não conheço nenhum método específico para execução a seco, mas podemos usar algumas precauções para entender um script desconhecido.

  1. Use um ambiente chroot para executar seu script de depuração. Ele atuará como um sandbox e fornecerá proteção contra a exclusão / modificação de arquivos principais do sistema.
  2. Use bash -n <script> para a verificação de sintaxe . Do link
  3. do gnu bash

-n Read commands but do not execute them; this may be used to check a script for syntax errors. This option is ignored by interactive shells.

  1. Leia o script pelo menos uma vez. Você pode usar a instrução echo para depuração , conforme mencionado na resposta do usuário191016 .
    • Fique atento a códigos suspeitos ou perigosos.
    • por exemplo. relacionado a rm, comandos afetando / dev / sda etc.
  2. Sempre tente executar scripts como usuário normal, evite executar scripts desconhecidos como root.
  3. Você pode definir o alias para criar um comando que possa modificar os arquivos como interativos no início do script Exemplo %código% Para editores de fluxo como sed alias rm="rm -i" alias cp="cp -i" alias mv="mv -i" (-i modifica o arquivo no lugar sem -i faz uma execução seca para sed, verifique a página man para detalhes) Você pode copiar o comando completo e executar. É apenas antes do comando real que irá mostrar a saída na tela, em seguida, use o comando para aguardar a entrada do usuário para continuar. Exemplo %código% Substitua-o por sed -i

Além disso, é sempre recomendável manter os pontos de backup no sistema, para que os dados de emergência possam ser restaurados.

    
por 20.07.2016 / 15:23
2

Aqui está uma pequena construção que gosto de usar:

#!/bin/sh

verbose=false
really=true

# parse arguments
while [ $# -ge 1 ]
do
  case "$1" in
    -v) verbose=true ;;
    -n) really=false; verbose=true ;;
  esac
  shift
done

doCmd() {
  if $verbose; then echo "$@"; fi
  if $really; then "$@"; fi
}

doCmd make foo
doCmd rm -rf /tmp/installdir
doCmd mkdir /tmp/installdir
doCmd whatever
doCmd blah blah
    
por 05.08.2016 / 23:15
1

Se você quiser impedir que as modificações aconteçam, você pode executar o script como um usuário sem privilégios:

sudo -u nobody ./scr.sh

No seu exemplo, isso executará FN="filename" como de costume. Embora tecnicamente também execute o comando rm -f ${FN} , nada acontecerá se nobody não tiver as permissões necessárias para excluir o arquivo.

Naturalmente, isso causará problemas no fluxo de trabalho condicional. O fato de que o comando rm falhou pode afetar outras partes do script.

    
por 16.01.2013 / 21:20