Como executar o script bash linha por linha?

93

Se eu inserir a opção bash -x , ele mostrará toda a linha. Mas o script será executado normalmente.

Como posso executar linha por linha? Então eu posso ver se ele faz a coisa certa, ou aborta e conserto o bug. O mesmo efeito é colocado readem cada linha.

Rodrigo
fonte
1
Talvez de forma mais ampla, consulte também stackoverflow.com/questions/951336/how-to-debug-a-bash-script/…
tripleee

Respostas:

126

Você não precisa colocar uma leitura em todas as linhas, apenas adicione uma armadilha como a seguinte em seu script bash, tem o efeito que você deseja, por exemplo.

#!/usr/bin/env bash
set -x
trap read debug

< YOUR CODE HERE >

Funciona, apenas testei com bash v4.2.8 e v3.2.25.


VERSÃO MELHORADA

Se o seu script estiver lendo conteúdo de arquivos, o listado acima não funcionará. Uma solução alternativa pode ser semelhante ao exemplo a seguir.

#!/usr/bin/env bash
echo "Press CTRL+C to proceed."
trap "pkill -f 'sleep 1h'" INT
trap "set +x ; sleep 1h ; set -x" DEBUG

< YOUR CODE HERE >

Para parar o script, você teria que eliminá-lo de outro shell neste caso.


ALTERNATIVA 1

Se você simplesmente deseja esperar alguns segundos antes de prosseguir para o próximo comando em seu script, o exemplo a seguir pode funcionar para você.

#!/usr/bin/env bash
trap "set +x; sleep 5; set -x" DEBUG

< YOUR CODE HERE >

Estou adicionando set + xe set -x no comando trap para tornar a saída mais legível.

mashup orgânico
fonte
1
Então, como você avança para a próxima linha (executa o próximo comando)?
David Doria
2
Ele intercepta uma leitura de cada comando. A única coisa que você precisa fazer é pressionar voltar para ir para o próximo comando
organic-mashup
1
se você tiver linhas de comando como esta "while read line; faça echo $ line; done <somefile" esse método não funciona porque "trap read DEBUG" lê a linha de somefile
mug896
3
Como você faz isso parar? Depois que eu passo pelo script até o final, o shell age como se o script ainda estivesse em execução.
slashdottir
1
Mude para trap 'read -u1' debugpara substituir o problema de redirecionamento de leitura de arquivo.
user3132194
23

Talvez o BASH Debugger seja algo para você.


fonte
3
Esta é realmente a melhor solução. Permite visualizar a linha antes de ser executada (e muito mais). Na maioria dos sistemas, ele pode ser instalado apt-get install bashdb. Então você só precisa executar bashdb your_command.sh, digitar stepe clicar em retorno de carro depois disso.
Studgeek
1
@studgeek não está disponível no Redhat / CentOS etc., então eu não chamaria isso de "a maioria dos sistemas".
Sajuuk de
@Sajuuk, pode não estar empacotado , mas está absolutamente disponível .
Charles Duffy,
macOS:brew install bashdb
boweeb
@CharlesDuffy: também não está nos repositórios padrão do Ubuntu.
Dan Dascalescu
2

Se o seu script bash é realmente um monte de comandos únicos que você deseja executar um por um, você poderia fazer algo assim, que executa cada comando um por um quando você incrementa uma variável LN, correspondendo ao número da linha que deseja executar . Isso permite que você apenas execute o último comando novamente de forma super fácil, e então você apenas incremente a variável para ir para o próximo comando.

Assumindo que seus comandos estão em um arquivo "it.sh", execute o seguinte, um por um.

$ cat it.sh
echo "hi there"
date
ls -la /etc/passwd

$ $(LN=1 && cat it.sh | head -n$LN | tail -n1)
"hi there"

$ $(LN=2 && cat it.sh | head -n$LN | tail -n1)
Wed Feb 28 10:58:52 AST 2018

$ $(LN=3 && cat it.sh | head -n$LN | tail -n1)
-rw-r--r-- 1 root wheel 6774 Oct 2 21:29 /etc/passwd
Brad Parks
fonte
1

Dê uma olhada em bash-stepping-xtrace .

Ele permite o stepping xtrace.

Mug896
fonte
1

xargs: pode filtrar linhas

cat .bashrc | xargs -0 -l -d \\n bash
  • -0 Tratar como entrada bruta (sem escape)
  • -l Separe cada linha (não por padrão para apresentações)
  • -d \\ n O separador de linha
Tinmarino
fonte