Eu gostaria de implementar um zsh
script que se comporte de maneira diferente dependendo se foi invocado diretamente na CLI do shell ou não.
A princípio pensei que o script poderia fazer isso procurando i
no valor de $-
, mas me enganei.
Na verdade, quando executo o script abaixo na linha de comando
#!/bin/zsh
printf -- '%s\n' "$-"
...a saída que recebo não inclui i
1 .
Existe alguma outra maneira para o meu script de shell descobrir essas informações?
NB: Embora eu esteja trabalhando em um zsh
roteiro no momento, eu também gostaria de saber qual seria a resposta para um bash
roteiro. Se a resposta depende do OS
, estou interessado principalmente em Linux e Darwin.
1 A saída do script é 569X
, se alguém quiser saber.
$-
contémi
quando o próprio shell é um shell interativo, quando emite prompts, permite inserir e editar linhas de comando no terminal, faz controle de trabalho etc.Um script normalmente é interpretado por um shell não interativo. Se você chamar o script como
./the-script
ouzsh ./the-script
, essazsh
instância não será interativa. A única vez que seu script será interpretado por um shell interativo é quando você diz ao seu shell interativo para interpretar o código nele com coisas comosource ./the-script
oueval "$(<the-script)"
.Aqui, parece-me que você quer saber se o script é invocado de dentro de um terminal, como você deseja saber se um usuário pode interagir com ele por meio de um terminal.
Que o comando
[
/test
(que está embutido no zsh e bash e na maioria dos outros shells do tipo Bourne, mas também deve existir como um comando autônomo em sistemas POSIX) pode informar com seu-t
operador. Esse-t
operador recebe um¹ argumento numérico que é um descritor de arquivo.[ -t 0 ]
outest -t 0
retorna true se o descritor de arquivo 0 estiver aberto em um dispositivo terminal. Descritor de arquivo 0 é entrada padrão , 1 é saída padrão , 2 é erro padrão , todos os outros fds não têm nenhum significado especial reservado.Então, no seu script, você pode fazer:
Se você quiser verificar se o script é executado de dentro de uma sessão de terminal, mesmo que sua entrada e/ou saída possa ser redirecionada para algum outro arquivo que não o dispositivo de terminal, você pode verificar se há um terminal conectado à sessão do script com algo como :
Se você quiser saber qual é o dispositivo terminal:
(veja este Q&A de acompanhamento para a razão por trás dessa dancinha com fd 3).
¹ Em implementações
test
/ anteriores[
, esse argumento era opcional e[ -t ]
era abreviação de[ -t 1 ]
. Isso não é mais permitido pelo POSIX, pois entra em conflito com o[ "$var" ]
caso de uso que é abreviado para[ -n "$var" ]
. Ainda assim, você descobrirá queksh93
ainda verifica se stdout vai para um tty com[ -t ]
though somente quando-t
é literal;var=-t; [ "$var" ]
retorna true mesmo se stdout não estiver em um terminal.