Avvio di Bash in dettaglio

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.

Avvio di Bash in dettaglio

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 myprogram

Script 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 bash

Il Dockerfile si trova qui.

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.log

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS 🔥 Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS - ProHoster