Se hai trovato questa pagina tramite una ricerca, stai sicuramente cercando di risolvere un problema con l'esecuzione di bash.
Potrebbe essere che nel tuo ambiente bash non venga impostata la variabile d'ambiente e non capisci perché. Potresti aver inserito cose in vari file di avvio bash o nei profili, o in tutti i file a caso, finché non ha funzionato.
In ogni caso, il senso di questa nota è di spiegare nel modo più semplice possibile la procedura di avvio di bash, in modo che tu possa affrontare i problemi.
Diagramma
Questo diagramma riassume tutti i processi di avvio di bash.

Ora esaminiamo più nel dettaglio ogni parte.
Shell di accesso?
Prima devi decidere se ti trovi in una shell di accesso (login shell) o no.
La shell di accesso è la prima shell che incontri quando accedi al sistema per una sessione interattiva. La shell di accesso non richiede l'inserimento di nome utente e password. Puoi forzare l'avvio della shell di accesso aggiungendo il flag --login quando chiami bash, per esempio:
bash --login
La shell di accesso configura l'ambiente base al primo avvio della shell bash.
Interattiva?
Poi devi determinare se la shell è interattiva o meno.
Puoi verificarlo controllando la presenza della variabile PS1 (imposta la funzione di input dei comandi):
if [ "${PS1-}" ]; then
echo interattiva
else
echo non interattiva
fi Oppure controllando se è impostato il parametro -i, usando la variabile speciale con il trattino - in bash, ad esempio:
$ echo $-
Se nell'output c'è il carattere i, allora la shell è interattiva.
Nella shell di accesso?
Se ti trovi in una shell di accesso, bash cerca il file /etc/profile e lo esegue, se esiste.
Poi cerca uno di questi tre file nell'ordine seguente:
~/.bash_profile ~/.bash_login ~/.profile
Quando ne trova uno, lo esegue e salta gli altri.
Nella shell interattiva?
Se ti trovi in una shell interattiva senza accesso (non-login shell), si presume che tu sia già passato per la shell di accesso, l'ambiente è configurato e verrà ereditato.
In questo caso vengono eseguiti in ordine i seguenti due file, se esistono:
/etc/bash.bashrc ~/.bashrc
Nessuna opzione?
Se non ti trovi né in una shell di accesso né in una shell interattiva, il tuo ambiente sarà davvero vuoto. Questo causa molta confusione (vedi sotto riguardo ai compiti cron).
In questo caso bash guarda la variabile BASH_ENV del tuo ambiente e crea il file corrispondente indicato lì.
Difficoltà tipiche e regole empiriche
Compiti cron
Nel 95% dei casi, il debug dell'avvio di bash è legato al fatto che il compito cron non funziona come previsto.
Questo maledetto compito funziona correttamente quando lo eseguo nella riga di comando, ma fallisce quando viene eseguito in crontab.
Qui due ragioni:
- I compiti cron non sono interattivi.
- A differenza degli script nella riga di comando, i compiti cron non ereditano l'ambiente della shell.
Di solito non te ne accorgi e non te ne preoccupi che lo script della shell non sia interattivo, perché l'ambiente viene ereditato dalla shell interattiva. Questo significa che tutto PATH e alias è impostato come ti aspetti.
Ecco perché spesso è necessario impostare un specifico PATH per il compito cron, come qui:
* * * * * PATH=${PATH}:\/path\/to\/my\/program\/folder myprogramScript che si chiamano a vicenda
Un'altra problematica comune, quando gli script sono erroneamente configurati per chiamarsi a vicenda. Ad esempio, /etc/profile si riferisce a ~/.bashrc.
Di solito accade quando qualcuno ha cercato di risolvere un errore e per qualche motivo tutto ha funzionato bene. Sfortunatamente, quando è necessario separare questi diversi tipi di sessioni, sorgono nuovi problemi.
Immagine Docker in sandbox
Per sperimentare con l'avvio della shell, ho creato un'immagine Docker da usare per il debugging dell'avvio della shell in un ambiente sicuro.
Avvio:
$ docker run -n bs -d imiell\/bash_startup
$ docker exec -ti bs bashIl Dockerfile si trova .
Per forzare il login e simulare la shell di accesso:
$ bash --login Per controllare l'insieme delle variabili BASH_ENV:
$ env | grep BASH_ENV Per il debugging crontab ogni minuto verrà eseguito un semplice script (in /root/ascript):
$ crontab -l
$ cat \/var\/log\/script.logFonte: habr.com
