Um shell interativo pode se tornar não interativo ou vice-versa?
Nota: Pesquisei bastante a questão básica "Qual é a diferença entre interativo e não interativo?", E os resultados de minha pesquisa me levaram a fazer essa pergunta.
Esta pergunta tem um preâmbulo longo em parte porque é crucial que tipo de definição usamos para "interativo" para respondê-la. Uma definição pode ser um rótulo arbitrário para um determinado conjunto; pode ser descritivo de várias propriedades; ou pode fornecer informações que você pode usar para prever o comportamento e entender o propósito. Esse último tipo pode ser chamado de "definição de ação" ou "definição dinâmica" e é o mais útil.
Em man 1p sh
, é dada a seguinte definição de um shell interativo:
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.
Com a menção de "-i option" e o uso da palavra "operandos", isso se refere à invocação de um shell , não a atributos que poderiam ser examinados em um shell em execução.
A página de manual do Bash define um pouco de maneira diferente:
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.
A definição na primeira frase novamente refere-se apenas ao início de um shell.
A segunda frase (na minha leitura) define condições que são usadas como proxies para estabelecer se o shell foi iniciado das maneiras específicas definidas para torná-lo "interativo".
Observe que eu não interpreto esta frase como: "Um shell bash é interativo se e somente se $-
incluir 'i'". $-
parece ser apenas um indicador útil, não uma definição de interativo. Isso é crucialmente relevante para minha pergunta.
Ambos (a sh
definição POSIX e Bash) são definições mecânicas que informam em que circunstâncias o rótulo "interativo" se aplica a um shell que você iniciou. Eles não são definições de ação , pois não dão implicações a esse rótulo.
No entanto, vejo que em todo o restante da página de manual do Bash são espalhadas referências ao shell se comportando de certas maneiras "a menos que seja um shell interativo" ou "apenas em shells interativos, ou se a opção _____ estiver configurada". (Existem inúmeros exemplos e esse não é o ponto principal desta pergunta.)
Portanto, aceito que "interativo" é apenas um rótulo conveniente para a coleção de comportamentos "interativos" padrão (configurações de opções) descritos em todo o restante da página do manual. Não é um termo ou objeto fundamental em si; não possui definição autoritativa fora do código-fonte do shell. (Diferente, por exemplo, dos termos "descritor de arquivo aberto" ou "processo parado", que se referem a abstrações incorporadas ao design do próprio kernel.)
(Embora também esteja definido na definição de POSIX de sh
, essa página de manual [ man 1p sh
] tem muito menos usos de "a menos que o shell seja interativo" e de instruções semelhantes que o man bash
possuam, e se concentra quase exclusivamente nas diferenças de tempo de invocação, portanto, focarei no Bash deste ponto em diante.)
Algumas das implicações de um shell ser "interativo" são relevantes apenas no momento da chamada , como quais arquivos são originados pelo shell antes de ler outros comandos. No entanto, não são as implicações (pelo menos em Bash) que são relevantes a qualquer momento. Portanto, deve haver uma maneira de dizer, para qualquer shell em execução , se é interativo ou não.
A execução set +i
em um shell Bash interativo faz com que 'i' seja removido do conteúdo de $-
.
A pergunta é: isso realmente significa que o shell não é mais interativo?
Pela definição exata de Bash, não deveria, pois em nenhum lugar da definição é necessário que 'i' esteja presente em $-
:
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.
Uma leitura estrita da definição exata também levanta a questão: se o stdin ou stderr de um terminal interativo são redirecionados para que não sejam mais conectados aos terminais, o shell se torna não interativo?
( Parece que a resposta para essa pergunta é "não" e a página de manual poderia ter incluído o modificador: "cuja entrada e erro padrão estão conectados aos terminais ... no momento da invocação " , mas não sei definitivamente.)
Se a resposta for "Não, um shell não pode se tornar não interativo, nem vice-versa", então qual é a maneira definitiva de determinar se o shell é interativo?
Dito de outra maneira: se houver comportamentos de um "shell interativo" que persistem depois set +i
, que é usado para determinar que esses comportamentos devem continuar sendo aplicados?
Para que não duvido que alguém que: Não são comportamentos de um shell invocou interativa que persistem após set +i
e comportamentos de um shell invocado não interativa que persistem após set -i
. Por exemplo, considere o seguinte trecho de 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.
Assim, desabilitando o interactive_comments
opção, podemos ver uma diferença entre shells interativos e não interativos. A persistência dessa diferença é demonstrada pelo seguinte 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
Isso confirma que "interativo" e "tem i
o valor de $-
" são não equivalentes.
Um teste semelhante usando ${parameter:?word}
um parâmetro não definido produz resultados semelhantes, confirmando novamente que $-
não é a "fonte da verdade" para a interatividade do shell.
Então, finalmente, onde está armazenada a característica definitiva de 'interatividade' de um shell?
E, um shell interativo pode se tornar não interativo ou vice-versa? (... alterando essa característica?)