È possibile che ci sia una shell di login non interattiva?


11

Nell'interpretazione di questo diagramma di flusso

inserisci qui la descrizione dell'immagine

Ho scoperto che in man bash:

Quando bash viene invocato come shell di login interattiva o come shell non interattiva con l'opzione --login, legge prima ed esegue i comandi dal file / etc / profile, se quel file esiste.

Ciò afferma che le shell di login interattive leggono /etc/profile(senza --noprofile)

Inoltre, shell non interattive con l'opzione --loginread/etc/profile

Ciò sembra lasciare alcune possibili shell di login (in cui $0inizia con a -) che non interattive (esegui uno script, forse semplice come date) potrebbero non leggere (sorgente) /etc/profile.

Per confermare o negare questa idea:

Prima ho provato a usare su -l -, che avvia una shell di login con a -come primo carattere ma non riesco a renderlo non interattivo (ed essere in grado di presentare i test per sondarlo).

Chiamando qualcosa di simile

$ bash -c 'date' -bash

Non segnala di essere una shell di accesso (anche se il primo carattere è a -).

Prova questo per rivelare il dettaglio:

   $ bash -c 'echo "$0 $- ||$(shopt -p login_shell)||";date' -bash
      -bash hBc ||shopt -u login_shell||
      Fri Aug 19 06:32:31 EDT 2016

Il $0ha una -come primo carattere, non c'è i(interattiva) nel valore $-ma non viene riportato come un login_shell(-u). In questo caso, / etc / profile non è stato letto, ma non sono sicuro che questo sia il test giusto.


C'è anche la menzione di "rare shell di login non interattive" in questa risposta senza essere abbastanza specifiche per questa domanda.


La conclusione di questo ragazzo è che /etc/profilesi legge sempre.

Leggi la tabella riepilogativa: leggi le shell di login interattive e non interattive /etc/profile


E, se gli esempi di questa pagina sono corretti:

Some examples

$ su bob                   # interactive non-login shell
$ su - bob                 # interactive login shell
$ exec su - bob            # interactive login shell
$ exec su - bob -c 'env'   # non-interactive login shell
$ ssh bob@example.com      # interactive login shell, `~/.profile`
$ ssh bob@example.com env  # non-interactive non-login shell, `~/.bashrc`

Il test dei exec su - bob -c 'env'rapporti che è /etc/profilestato letto.


In breve:

È possibile avere una shell di login non interattiva (non chiamata con --login o -l)?

E se vero, sta leggendo il /etc/profilefile?

Se quanto sopra è vero, dobbiamo concludere che TUTTE le shell di login [interattive (o meno)] leggono / etc / profile (senza alcuna --noprofileopzione).

Nota: per rilevare che / etc / profile viene letto, basta aggiungere all'inizio del file questo comando:

echo "'/etc/profile' is being read"

Risposte:


2

Una shell di login non interattiva è insolita, ma possibile. Se si avvia la shell con l'argomento zeroth (che normalmente è il nome dell'eseguibile) impostato su una stringa che inizia con a -, si tratta di una shell di accesso, che sia interattiva o meno.

$ ln -s /bin/bash ./-bash
$ echo 'shopt -p login_shell; echo $-' | HOME=/none PATH=.:$PATH -bash
shopt -s login_shell
hB

Il tuo tentativo bash -c date -bashnon ha funzionato perché non dice alla shell di essere una shell di accesso: l'argomento zeroth è bash, no -bash. Dopo che bash ha avviato, imposta la variabile $0al -bashposto del ragionamento zeroth, ma l'argomento zeroth è ciò che conta.

È possibile eseguire una shell di accesso non interattivo con su -lo su -, ma è necessario disporre che l'input standard non sia un terminale mentre si può ancora essere autorizzati (senza dover digitare una password o disporre che la password sia all'inizio del ingresso). Potrebbe essere più facile con sudo: esegui sudo trueper ottenere una credenziale di presenza, quindi mentre la credenziale è ancora valida esegui echo 'shopt -p login_shell; echo $-' | sudo -i.

Vedi anche Differenza tra Shell di accesso e Shell non di accesso?


4

Ho visto ambienti di accesso grafici che fanno:

exec "$SHELL" -l -c 'exec start-window-or-session-manager'

o l'equivalente di:

exec -a "-$SHELL" "$SHELL" <<EOF
exec start-window-or-session-manager
EOF

In modo che il file di inizializzazione della sessione (come ~/.profileper le shell tipo Bourne (e quelli corrispondenti /etcper alcuni)) sia letto e applicato.

Il primo non funziona con tutte le shell. -lè supportato da un gran numero di shell, ma non tutte, e su alcune, come csh/ tcsh, non possono essere utilizzate -c. Tuttavia, il primo carattere argv[0]dell'essere -è compreso da tutte le shell, poiché è ciò che loginserve per dire alle shell che sono shell di login.

Nel secondo caso, lo stdin di quella shell è qualcosa di diverso da un ttydispositivo ( <<è implementato da un file regolare temporaneo o da una pipe a seconda della shell), quindi la shell non è interattiva (la definizione di essere interattivo quando un essere umano interagisce con esso).


Il primo sta usando l' --loginopzione. Per il secondo, se lo faccio exec -a "-bash" "bash" <<<"shopt -p login_shell; echo $0 $-"ottengo (codificato in C qoutes) $'/etc/profile read\nshopt -s login_shell\nbash himBH', quindi è login ma è interattivo. Abbiamo bisogno di login e non interattivo . Cosa mi manca?

@sorontar, con <<<"$-", che $-viene espanso dalla shell chiamante a causa delle doppie virgolette. La shell chiamata non è interattiva perché il suo stdin non è un tty.
Stéphane Chazelas,

Ah, sì, lei ha ragione, signore. Tuttavia, correggendo l'errore, possiamo farlo: exec -a "-bash" "bash" <<\EOF shopt -p login_shell; echo $0 $- EOFper ottenere questa conferma: $'/etc/profile read stdin: is not a tty shopt -s login_shell -bash hB'Quindi, sì, è possibile una shell di accesso non interattiva, che continua a leggere /etc/profile. Dobbiamo concludere che TUTTE le shell di login leggono /etc/profile?

ksh rende abbastanza chiaro che si tratta di una shell di login non interattiva , prova exec -a "-ksh" "ksh" <<\EOF echo $0; set -o EOF, :).

1
@sorontar, penso che puoi aspettarti che la maggior parte delle implementazioni della shell leggano i loro file di inizializzazione della sessione quando vengono chiamati come shell di login. Quali sono dipendono dall'implementazione e dalla versione della shell. Nel caso di bash, la gestione dei file di avvio è IMO piuttosto incasinata, scoprirai che alcuni sistemi l'hanno corretta per avere un comportamento più ragionevole aggiungendo ancora più variazioni.
Stéphane Chazelas,

3

Sì, sono possibili shell di login non interattive

$ head -1 /etc/profile
echo PROFILE BEING READ

$ echo echo hello | su -
PROFILE BEING READ
stdin: is not a tty
hello

$

Questo è simile a questo semplificata: su -c 'echo hello' -. Il che, per testare quello che ci serve, dovrebbe essere scritto come: su -c 'echo $0 $-; shopt -p login_shell' -per ottenere questa risposta conferma (codificati tra virgolette C): $'/etc/profile read \n -su hBc \n shopt -s login_shell'. Ciò conferma che è stata eseguita una shell di accesso non interattiva e che, nel frattempo, è stato letto il profilo / etc / profile. Grazie.

0

È possibile avere una shell di login non interattiva (non chiamata con --login o -l)?

SÌ.

$ (exec -a '-' bash -c 'shopt -q login_shell && echo login shell')

Tuttavia, si noti che /etc/profilenon verrebbe utilizzato per una shell di accesso non interattivo a meno che non --loginvenga fornito l' argomento.

Un linguaggio comune che invoca una shell di accesso non interattiva è:

$ su - someuser -c somecommand

Ma questo subisce il fatto che /etc/profilenon viene eseguito.

È possibile cambiare questo comportamento ma implica la personalizzazione del codice sorgente di Bash in fase di compilazione decommentando un'opzione trovata in config-top.h :

/* Define this to make non-interactive shells begun with argv[0][0] == '-'
run the startup files when not in posix mode. */
/* #define NON_INTERACTIVE_LOGIN_SHELLS */

Quando ho ricercato questa suanomalia , ho scoperto che altre shell includevano zshe dashnon hanno questa discrepanza.

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.