Una shell interattiva può diventare non interattiva o viceversa?
Nota: ho fatto molte ricerche sulla domanda di base, "Qual è la differenza tra interattivo e non interattivo?", E i risultati della mia ricerca mi hanno portato a porre questa domanda.
Questa domanda ha in parte un lungo preambolo perché è cruciale quale tipo di definizione utilizziamo per "interattivo" per rispondere. Una definizione potrebbe essere un'etichetta arbitraria per un determinato set; potrebbe essere descrittivo di varie proprietà; o può darti informazioni che puoi usare per prevedere il comportamento e capire lo scopo. Quest'ultimo tipo possiamo chiamare una "definizione di azione" o una "definizione dinamica" ed è la più utile.
In man 1p sh
, viene fornita la seguente definizione di shell interattiva:
If the -i option is present, or if there are no operands and the shell’s standard input and standard error are attached to a terminal, the shell is considered to be interactive.
Dalla menzione di "opzione -i" e dall'uso della parola "operandi", questo si riferisce all'invocazione di una shell , non ad attributi che potrebbero essere esaminati in una shell in esecuzione.
La pagina man di Bash la esprime in modo leggermente diverso:
An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option. PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state.
La definizione nella prima frase si riferisce ancora solo all'inizio di una shell.
La seconda frase (nella mia lettura) definisce le condizioni che vengono utilizzate come proxy per stabilire se la shell è stata avviata nei modi particolari definiti come "interattivi".
Si noti che io non interpreto questa frase come: "shell bash è interattiva A se e solo se $-
. Include 'i'" $-
sembra essere solo un utile indicatore, non una definizione di interattivo. Questo è di fondamentale importanza per la mia domanda.
Entrambi (la sh
definizione POSIX e quella di Bash) sono definizioni meccaniche che indicano in quali circostanze l'etichetta "interattivo" si applica a una shell che hai avviato. Non sono definizioni di azione in quanto non danno implicazioni a questa etichetta.
Tuttavia, vedo che in tutto il resto della pagina man di Bash sono presenti dei riferimenti sparsi alla shell che si comportano in determinati modi "a meno che non sia una shell interattiva" o "solo nelle shell interattive o se è impostata l'opzione _____". (Ci sono numerosi esempi e non è questo il punto principale di questa domanda.)
Quindi accetterò che "interattivo" è solo un'etichetta conveniente per la raccolta di comportamenti "interattivi" predefiniti (impostazioni delle opzioni) descritti nel resto della pagina man. Non è un termine o un oggetto fondamentale in sé; non ha una definizione autorevole al di fuori del codice sorgente della shell. (A differenza, ad esempio, dei termini "descrittore di file aperto" o "processo arrestato" che si riferiscono alle astrazioni incorporate nella progettazione del kernel stesso.)
(Sebbene sia anche definito nella definizione POSIX di sh
, quella pagina man [ man 1p sh
] ha molti meno usi di "a meno che la shell non sia interattiva" e dichiarazioni simili rispetto a quelle che man bash
ha, e si concentra quasi esclusivamente sulle differenze di tempo di invocazione, quindi mi concentrerò su Bash da questo punto in poi.)
Alcune delle implicazioni di una shell come "interattiva" sono comunque rilevanti solo al momento dell'invocazione , come ad esempio quali file provengono dalla shell prima che legga altri comandi. Tuttavia, ci sono implicazioni (almeno in Bash) che sono rilevanti in qualsiasi momento. Quindi deve esserci un modo per dire, per ogni data shell in esecuzione , se è interattiva o no.
L'esecuzione set +i
in una shell Bash interattiva comporta la rimozione di 'i' dal contenuto di $-
.
La domanda è: questo significa che la shell non è più interattiva?
Secondo l'esatta definizione di Bash, non dovrebbe, poiché in nessuna parte della definizione è richiesto che 'i' sia presente in $-
:
An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option.
Una lettura rigorosa della definizione esatta solleva anche la domanda: se lo stdin o lo stderr di un terminale interattivo vengono reindirizzati in modo che non siano più collegati ai terminali, la shell diventa non interattiva?
( Sembra che la risposta a questa sia "no" e la pagina man avrebbe potuto includere il modificatore: "i cui input ed errori standard sono entrambi collegati ai terminali ... al momento dell'invocazione " , ma non lo so definitivamente.)
Se la risposta è "No, una shell non può diventare non interattiva, né viceversa", qual è il modo definitivo per determinare se la shell è interattiva?
Detto in altro modo: se ci sono comportamenti di una "shell interattiva" che persistono dopo set +i
, a che cosa serve determinare che tali comportamenti dovrebbero continuare ad applicarsi?
Perché nessuno ne dubiti: ci sono comportamenti di una shell invocati in modo interattivo che persistono dopo set +i
e comportamenti di una shell invocati in modo non interattivo che persistono dopo set -i
. Per un esempio, considera il seguente estratto da man bash
:
COMMENTS In a non-interactive shell, or an interactive shell in which the inter- active_comments option to the shopt builtin is enabled (see SHELL BUILTIN COMMANDS below), a word beginning with # causes that word and all remaining characters on that line to be ignored. An interactive shell without the interactive_comments option enabled does not allow comments. The interactive_comments option is on by default in interac- tive shells.
Quindi, disabilitando l' interactive_comments
opzione, possiamo vedere una differenza tra shell interattive e non interattive. La persistenza di questa differenza è dimostrata dal seguente script:
#!/bin/bash
# When the testfile is run interactively,
# all three comments will produce an error
# (even the third where 'i' is not in '$-').
# When run noninteractively, NO comment will
# produce an error, though the second comment
# is run while 'i' IS in '$-'.
cat >testfile <<'EOF'
shopt interactive_comments
shopt -u interactive_comments
shopt interactive_comments
echo $-
#first test comment
set -i
echo $-
#second test comment
set +i
echo $-
#third test comment
EOF
echo 'running bash -i <testfile'
bash -i <testfile
echo 'running bash <testfile'
bash <testfile
Ciò conferma che "interattivo" e "ha i
nel valore di $-
" non sono equivalenti.
Un test simile che utilizza ${parameter:?word}
un parametro non impostato produce risultati simili, confermando ancora una volta che $-
non è la "fonte di verità" per l'interattività della shell.
Quindi, infine, dove è memorizzato il tratto definitivo di "interattività" di una shell?
E una shell interattiva può diventare non interattiva o viceversa? (... cambiando questo tratto?)