Acho que entendo as diferenças entre um shell interativo, um login e um lote. Consulte os seguintes links para obter mais ajuda:
- Qual é a diferença entre um shell bash de 'Login' e um 'Interactive' (no site associado: serverfault.com )
- 2.1: Tipos de shell: shells interativos e de login (do Guia do usuário ao Z-Shell )
Minha pergunta é: como posso testar com um comando / condição se estiver em um shell interativo, de login ou de lote?
Estou procurando um comando ou condição (que retorne true
ou false
) e que também possa ser colocado em uma instrução if. Por exemplo:
if [[ condition ]]
echo "This is a login shell"
fi
Respostas:
Estou assumindo um
bash
shell, ou similar, já que não há shell listado nas tags.Para verificar se você está em um shell interativo:
Para verificar se você está em um shell de login:
Por "lote", presumo que você queira dizer "não interativo", portanto a verificação de um shell interativo deve ser suficiente.
fonte
zsh
usuários, a verificação de um shell de login pode ser feita com:if [[ -o login ]] ...
$-
está sendo expandida no shell atual. Se você usar aspas simples em torno da expressão completa você vai obter o resultado correto:bash -c '[[ $- == *i* ]] && echo "Interactive" || echo "Not interactive"'
Em qualquer shell no estilo Bourne, a
i
opção indica se o shell é interativo:Não há uma maneira portátil e totalmente confiável de testar um shell de login. Ksh e zsh adicionam
l
a$-
. O Bash define alogin_shell
opção com a qual você pode consultarshopt -q login_shell
. Portably, teste se$0
começa com um-
: shells normalmente sabem que são shells de logon porque o chamador adicionou um-
prefixo ao argumento zero (normalmente o nome ou o caminho do executável). Isso falha ao detectar maneiras específicas de shell de chamar um shell de login (por exemploash -l
).fonte
$0
sempre começar com um,-
não importa como foi iniciado. Mas há pelo menos uma exceção: isso nem sempre é verdade com o bash, mesmo que seja para ser um shell de logon. Experimente na sua caixa: invoquebash --login
e$0
continue lendobash
.casca de peixe
Aqui está a resposta para o
fish
caso de outros usuários encontrarem essa página.Documentação de peixes: inicialização
fonte
csh / tcsh
Para
csh
etcsh
eu tenho o seguinte no meu.cshrc
arquivo:Especificamente para
tcsh
, a variávelloginsh
é configurada para um shell de logon:(
tcsh
também possui uma variávelshlvl
definida como o número de shells aninhados, em que o shell de login tem um valor de 1.)fonte
PS1
não funciona para testar um shell interativo. É quase sempre definido de forma interativa, mas você pode desmarcá-lo. Muitas vezes, é definido em um shell não interativo, porque muitos sistemas são enviados com oexport PS
in/etc/profile
.Outra maneira é verificar o resultado de
tty
fonte
[ -t 0 ]
para testar se STDIN é um tty. Você também pode usar 1 (STDOUT) ou 2 (STDERR), dependendo de suas necessidades.disown
viva,tty
funcionou melhor para saber que não é mais interativo, enquanto$-
não mudou; Ainda estou intrigado sobre qual é a melhor abordagem.[ -t 0 ]
. PS No meu comentário anterior, escrevi que “existe uma forte correlação” - eu esqueci “além do caso extremamente comum de um script iniciado com#!/bin/sh
ou similar”, que não é interativo, mas pode ser conectado a um terminal.O UNIX / Linux possui um comando para verificar se você está em um terminal.
fonte
dash
também.Você pode verificar se stdin é um terminal:
fonte
Para verificar se um script é executado em um shell interativo ou não interativo, verifico em meus scripts a presença de um prompt armazenado na
$PS1
variável:Isso eu aprendi aqui: https://www.tldp.org/LDP/abs/html/intandnonint.html
fonte
i
não é a opção correta para procurar.-i
é forçar um shell não interativo a se tornar interativo. A opção correta ativada automaticamente é-s
, mas o Bash infelizmente não lida com isso corretamente.Você precisa verificar se
$-
contéms
(isso é concedido para ser ativado automaticamente) ou se ele contémi
(isso não é concedido para ser ativado automaticamente, mas oficialmente acoplado apenas à-i
opção de linha de comando do shell).fonte
s
seria se o shell ler comandos do stdin, não se for interativo. Um shell interativo não necessariamente lê comandos do stdin (tentezsh -i < /dev/null
, embora o zsh pareça ser a exceção aqui). E um shell pode estar lendo comandos do stdin e não ser interativo (comosh < file
ouecho 'echo "$1"' | sh -s foo bar
).[[...]]
que implica ksh / bash / zsh. Como observação histórica, você tem um argumento de que o check-i
in$-
não funcionará no shell Bourne. Mas a verificaçãos
também não funcionará lá de maneira confiável. Você também deseja procurar por[ -t 0 ]
oui
; mesmo assim isso seria enganado em casos de canto comoecho 'exec < /dev/tty; that-check' | sh'