Come eseguire lo script bash riga per riga?


Risposte:


126

Non è necessario inserire una lettura in ogni riga, basta aggiungere una trappola come la seguente nel tuo script bash, ha l'effetto che desideri, ad es.

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

< YOUR CODE HERE >

Funziona, l'ho appena testato con bash v4.2.8 e v3.2.25.


VERSIONE MIGLIORATA

Se il tuo script sta leggendo il contenuto dai file, quanto sopra elencato non funzionerà. Una soluzione alternativa potrebbe essere simile al seguente esempio.

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

Per fermare lo script dovresti ucciderlo da un'altra shell in questo caso.


ALTERNATIVA 1

Se si desidera semplicemente attendere alcuni secondi prima di procedere al comando successivo nel proprio script, il seguente esempio potrebbe funzionare per voi.

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

< YOUR CODE HERE >

Sto aggiungendo set + x e set -x all'interno del comando trap per rendere l'output più leggibile.


1
Allora come passi alla riga successiva (esegui il comando successivo)?
David Doria

2
Cattura una lettura su ogni comando. L'unica cosa che devi fare è premere Invio per passare al comando successivo
organic-mashup

1
se hai righe di comando come questa "while read line; do echo $ line; done <somefile" quel metodo non funziona perché "trap read DEBUG" legge la riga da somefile
mug896

3
Come fai a fermarlo? Dopo aver eseguito lo script fino alla fine, la shell si comporta come se lo script fosse ancora in esecuzione.
slashdottir

1
Modificare in trap 'read -u1' debugper ignorare il problema di reindirizzamento della lettura del file.
user3132194

23

Forse il debugger BASH è qualcosa per te.


3
Questa è davvero la soluzione migliore. Consente di visualizzare la linea prima che venga eseguita (e molto altro). Sulla maggior parte dei sistemi può essere installato con apt-get install bashdb. Quindi devi solo eseguire bashdb your_command.sh, digitare stepe quindi premere il tasto di ritorno a capo.
studgeek

1
@studgeek non è disponibile su Redhat / CentOS ecc. quindi non lo chiamerei "la maggior parte dei sistemi".
Sajuuk

@ Sajuuk, potrebbe non essere confezionato , ma è assolutamente disponibile .
Charles Duffy

macOS:brew install bashdb
boweeb

@CharlesDuffy: non è nemmeno nei repository di Ubuntu predefiniti.
Dan Dascalescu

2

Se il tuo script bash è davvero un mucchio di comandi una tantum che vuoi eseguire uno per uno, potresti fare qualcosa del genere, che esegue ogni comando uno per uno quando incrementi una variabile LN, corrispondente al numero di riga che vuoi eseguire . Ciò ti consente di eseguire di nuovo l'ultimo comando in modo estremamente semplice, quindi incrementare la variabile per passare al comando successivo.

Supponendo che i tuoi comandi siano in un file "it.sh", esegui quanto segue, uno per uno.

$ 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


1

xargs: può filtrare le linee

cat .bashrc | xargs -0 -l -d \\n bash
  • -0 Considera come input non elaborato (senza escape)
  • -l Separa ogni riga (non di default per le performance)
  • -d \\ n Il separatore di riga
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.