Modo corretto di distribuire script di shell


8

Qual è il modo più appropriato per distribuire gli script di shell, se i comportamenti delle shell possono essere modificati sete quindi imprevedibili?

Ad esempio, rm *.txtnon verrebbe eseguito come previsto negli ambienti in cui set -fè stato eseguito. Come devo assicurarmi che rm *.txtrimuova tutti i file di testo in una directory corrente in qualsiasi ambiente?

Come devo assicurarmi che gli script di shell vengano eseguiti come previsto prima di distribuirli in generale?


shell_state=$(set +o) ... sceneggiatura ...eval "$shell_state"
mikeserv,

È possibile eseguire quei comandi nella parte superiore dello script stesso o modificare il #!per specificare quali opzioni di shell si desidera.
HalosGhost,

Risposte:


6

Gli script Shell vengono normalmente trattati come se fossero gli stessi di qualsiasi altro tipo di file eseguibile, come binari, script Python, script Perl o qualsiasi altro tipo di script. Hanno uno shebang nella parte superiore che indica al kernel di eseguirli attraverso la shell. Si prevede che vengano invocati allo stesso modo di qualsiasi altro comando.

Come tale, una nuova shell viene avviata ogni volta che viene invocato lo script e qualsiasi impostazione come quella set -fpresente nella shell invocante o in qualsiasi altra istanza della shell nel sistema è irrilevante.

Ovviamente è possibile per gli utenti procurarsi il tuo script invece di eseguirlo, ad esempio in questo modo:

. /path/to/your/script

o per eseguirlo in una shell che ha impostazioni non predefinite come questa:

sh -f /path/to/your/script

ma quelli non sono considerati modi normali o invocano il tuo script e gli utenti che lo fanno dovrebbero aspettarsi qualsiasi cosa ottengano di conseguenza.

Si noti che ci sono alcuni script che devono essere di provenienza, non eseguiti, perché il loro scopo è quello di modificare il CWD o impostare le variabili di ambiente che devono essere riflesse nell'ambiente della shell di approvvigionamento, ma sono in minoranza e di solito è fatto come parte di un protocollo concordato. Questi file possono essere considerati più simili a "plug-in" per qualsiasi sistema si aspettino di provenire, non tanto quanto script indipendenti. Ad esempio, i file in /etc/rc*.dentrata con nomi che finiscono in .shentrata provengono dal sottosistema dello script di avvio, non eseguiti, ed è documentato che questo è ciò che accadrà se si inserisce un file con tale nome in/etc/rc*.de quando è fatto è fatto apposta. La convenzione di denominare i file destinati ad essere acquistati anziché eseguiti in questo modo è seguita anche altrove, ma non universalmente.

È vero che i file destinati ad essere acquistati in questo modo devono occuparsi delle impostazioni che potrebbero essere presenti nell'ambiente del chiamante che potrebbero influenzare il comportamento della shell, ma il protocollo concordato dovrebbe idealmente promettere un ambiente di esecuzione prevedibile.


1
zshha una funzione che consente di ripristinare le opzioni su un set noto in un contesto locale ( emulate -L zsh) che viene ampiamente utilizzato in tutte le estensioni fornite con zsh e scritte come codice zsh. Guarda come il sistema di completamento bash fallisce miseramente se imposti alcune opzioni come failglob.
Stéphane Chazelas,

Alcune shell leggono il tuo file di personalizzazione anche quando invocate per interpretare gli script. Ecco perché di solito usi #! /bin/csh -finvece che #! /bin/cshad esempio.
Stéphane Chazelas,

@ StéphaneChazelas Haha, sì davvero. Naturalmente questo fa parte del perché usare csh è una cattiva idea , giusto? :-) Ma immagino che anche zsh lo abbia, sotto forma di zshenv. Attento a ciò che hai inserito zshenvper quel motivo!
Celada,

@ StéphaneChazelas a proposito, non è la prima volta che mi insegni qualcosa che non sapevo ( emulate -Lin questo caso) commentando una delle mie risposte, e lo apprezzo.
Celada,

Bene, ~/.zshenv(dove vuoi forzare le impostazioni (generalmente env vars) per tutte le zsh (interattive o no) invocate sotto il tuo nome e generalmente non usate se non per aggirare qualche altro problema non-zsh) è separato dal ~/.zshrc(interattivo shell di personalizzazione), quindi è una funzionalità, non un bug. (puoi usare zsh -f) Un bug è quando alcune shell bash non interattive leggono il tuo ~/.bashrc(come su ssh e devi aggiungere codice per proteggerti), o alcuni bash interattivi (quelli di login) non lo leggono (e di nuovo, devi aggiungere del codice ~/.bash_profileper aggirare il problema).
Stéphane Chazelas,
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.