GNU/Linux >> Linux Esercitazione >  >> Linux

Come leggere l'intero script della shell prima di eseguirlo?

Di solito, se modifichi uno scrpit, tutti gli utilizzi in esecuzione dello script sono soggetti a errori.

Per quanto ho capito, bash (anche altre shell?) Legge lo script in modo incrementale, quindi se hai modificato il file di script esternamente, inizia a leggere le cose sbagliate. C'è un modo per prevenirlo?

Esempio:

sleep 20

echo test

Se esegui questo script, bash leggerà la prima riga (diciamo 10 byte) e andrà a dormire. Quando riprende, possono esserci contenuti diversi nello script a partire dal decimo byte. Potrei essere nel mezzo di una riga nel nuovo script. Pertanto lo script in esecuzione verrà interrotto.

Risposta accettata:

Sì shell e bash in particolare, fai attenzione a leggere il file una riga alla volta, quindi funziona come quando lo usi in modo interattivo.

Noterai che quando il file non è ricercabile (come una pipe), bash legge anche un byte alla volta per essere sicuro di non leggere oltre il \n carattere. Quando il file è ricercabile, esegue l'ottimizzazione leggendo blocchi interi alla volta, ma cerca di nuovo dopo il \n .

Ciò significa che puoi fare cose come:

bash << \EOF
read var
var's content
echo "$var"
EOF

Oppure scrivi script che si aggiornano da soli. Cosa che non saresti in grado di fare se non ti desse quella garanzia.

Ora, è raro che tu voglia fare cose del genere e, come hai scoperto, quella funzione tende a intromettersi più spesso di quanto non sia utile.

Per evitarlo, puoi provare ad assicurarti di non modificare il file sul posto (ad esempio, modificare una copia e spostare la copia sul posto (come sed -i o perl -pi e alcuni editor lo fanno per esempio)).

Oppure potresti scrivere il tuo script come:

{
  sleep 20
  echo test
}; exit

(nota che è importante che il exit essere sulla stessa riga di }; però potresti anche metterlo tra le parentesi graffe poco prima di quella di chiusura).

oppure:

main() {
  sleep 20
  echo test
}
main "[email protected]"; exit

La shell dovrà leggere lo script fino a exit prima di iniziare a fare qualsiasi cosa. Ciò garantisce che la shell non leggerà più lo script.

Ciò significa che l'intero script verrà archiviato in memoria.

Ciò può influire anche sull'analisi dello script.

Ad esempio, in bash :

export LC_ALL=fr_FR.UTF-8
echo $'St\ue9phane'

Risulterebbe U+00E9 codificato in UTF-8. Tuttavia, se lo modifichi in:

{
  export LC_ALL=fr_FR.UTF-8
  echo $'St\ue9phane'
}

Il \ue9 verrà espanso nel set di caratteri che era in vigore al momento dell'analisi del comando, che in questo caso è prima l'export il comando viene eseguito.

Correlati:SSH – script per automatizzare scp in rete?

Nota anche che se il source alias . viene utilizzato il comando, con alcune shell, avrai lo stesso tipo di problema per i file di origine.

Non è il caso di bash sebbene la cui source comando legge il file completamente prima di interpretarlo. Se si scrive per bash in particolare, potresti effettivamente utilizzarlo, aggiungendo all'inizio dello script:

if [[ ! $already_sourced ]]; then
  already_sourced=1
  source "$0"; exit
fi

(Non ci farei affidamento però, poiché potresti immaginare le versioni future di bash potrebbe cambiare quel comportamento che attualmente può essere visto come una limitazione (bash e AT&T ksh sono le uniche shell simili a POSIX che si comportano in questo modo per quanto ne so) e il already_sourced il trucco è un po' fragile in quanto presuppone che la variabile non sia nell'ambiente, per non parlare del fatto che influisca sul contenuto della variabile BASH_SOURCE)


Linux
  1. Come ottenere l'indirizzo IP esterno in uno script di shell?

  2. Come eseguire il debug di uno script Bash?

  3. Come crittografare o rendere illeggibile lo script della shell?

  4. Come controllare la sottostringa in Shell Script Bash?

  5. Come la shell BASH carica i suoi file di configurazione in Linux

Come utilizzare il comando di lettura Bash

Come utilizzare la password crittografata nello script della shell Bash Linux

Personalizzazione della shell Bash

Come eseguire uno script Bash

Shell Script, letto sulla stessa riga dopo aver ripetuto un messaggio

Qual è la differenza tra l'esecuzione di uno script Bash e l'approvvigionamento?