É possível que exista um shell de login que não seja interativo?


11

Na interpretação deste fluxograma

insira a descrição da imagem aqui

Eu descobri que na festa do homem:

Quando o bash é chamado como um shell de login interativo ou como um shell não interativo com a opção --login, ele primeiro lê e executa comandos do arquivo / etc / profile, se esse arquivo existir.

Indica que os shells de logon interativo são lidos /etc/profile(sem --noprofile)

Além disso, shells não interativos com a opção --loginread/etc/profile

Isso parece deixar alguns possíveis shells de login (nos quais $0começa com a -) que não são interativos (executam um script, talvez tão simples quanto date) podem não ser lidos (fonte) /etc/profile.

Para confirmar ou negar esta ideia:

Primeiro, tentei usar su -l -, que inicia um shell de login com -o caractere primeiro, mas não consigo torná-lo não interativo (e consigo apresentar os testes para sondá-lo).

Chamando algo como

$ bash -c 'date' -bash

Não relata ser um shell de logon (mesmo que o primeiro caractere seja a -).

Tente isto para revelar os detalhes:

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

O $0tem um -como o primeiro caractere, não há i(interativo) no valor de, $-mas não é relatado como um login_shell(o -u). Nesse caso, o / etc / profile não foi lido, mas não tenho certeza se este é o teste certo.


Há também a menção de "conchas de login não interativas raras" nesta resposta sem ser suficientemente específico para esta pergunta.


A conclusão desse cara é que /etc/profileé sempre lida.

Leia a tabela de resumo: os shells de login interativos e não interativos são lidos /etc/profile


E, se os exemplos desta página estiverem corretos:

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`

O teste dos exec su - bob -c 'env'relatórios que /etc/profileforam lidos.


Em resumo:

É possível ter um shell de logon não interativo (não chamado com --login ou -l)?

E se for verdade, está lendo o /etc/profilearquivo?

Se o exposto acima for verdade, temos que concluir que TODAS as conchas de login [interativas (ou não)] leem / etc / profile (sem --noprofileopção).

Nota: para detectar que o / etc / profile está sendo lido, basta adicionar no início do arquivo este comando:

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

Respostas:


2

Um shell de logon não interativo é incomum, mas possível. Se você iniciar o shell com o argumento zeroth (que normalmente é o nome do executável) definido como uma sequência iniciada por a -, será um shell de login, seja interativo ou não.

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

Sua tentativa bash -c date -bashnão funcionou porque isso não diz ao shell para ser um shell de login: o argumento zeroth é bash, não -bash. Após o início do bash, ele define a variável $0em -bashvez do argumento zeroth, mas o argumento zeroth é o que importa.

Você pode executar um shell de logon não interativo com su -lou su -, mas precisa providenciar para que a entrada padrão não seja um terminal e ainda assim possa ser autorizada (sem precisar digitar uma senha ou fazer com que sua senha seja no início do entrada). Pode ser mais fácil com sudo: run sudo truepara obter uma credencial de presença, enquanto a credencial ainda é válida echo 'shopt -p login_shell; echo $-' | sudo -i.

Veja também Diferença entre o Shell de Login e o Shell Não-Login?


4

Eu já vi ambientes de login gráfico que:

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

ou o equivalente a:

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

Para que o arquivo de inicialização da sessão (como ~/.profilepara shells semelhantes a Bourne (e os correspondentes /etcpara alguns)) seja lido e aplicado.

O primeiro não funciona com todas as conchas. -lé suportado por um grande número de shells, mas nem todos, e em alguns, como csh/ tcsh, não podem ser usados -c. O primeiro caractere de argv[0]ser -é entendido por todos os shells, porém, como é o que ele loginusa para dizer aos shells que eles são shells de login.

No segundo caso, o stdin desse shell é algo que não é um ttydispositivo ( <<é implementado por um arquivo regular temporário ou um canal dependendo do shell), portanto o shell não é interativo (a definição de ser interativo quando um ser humano interage com isso).


O primeiro está usando a --loginopção Para o segundo, se eu exec -a "-bash" "bash" <<<"shopt -p login_shell; echo $0 $-"obtiver (codificado em C qoutes) $'/etc/profile read\nshopt -s login_shell\nbash himBH', é um login, mas é interativo. Precisamos de login e não interativos . O que é que estou perdendo?

@sorontar, with <<<"$-", que $-é expandido pelo shell de chamada devido às aspas duplas. O shell chamado não é interativo porque seu stdin não é um tty.
Stéphane Chazelas

Ah, sim, você está correto, senhor. No entanto, corrigindo o erro, podemos fazer o seguinte: exec -a "-bash" "bash" <<\EOF shopt -p login_shell; echo $0 $- EOFpara obter esta confirmação: $'/etc/profile read stdin: is not a tty shopt -s login_shell -bash hB'Então, sim, um shell de logon não interativo é possível e ainda é lido /etc/profile. Devemos concluir que TODAS as conchas de login são lidas /etc/profile?

O ksh deixa bem claro que é um shell de login não interativo , tente exec -a "-ksh" "ksh" <<\EOF echo $0; set -o EOF:).

1
@sorontar, acho que você pode esperar que a maioria das implementações de shell leia seus arquivos de inicialização de sessão quando chamados como shells de login. Quais são eles depende da implementação e versão do shell. No caso de bash, o manuseio de arquivos de inicialização é bastante IMO, você verá que alguns sistemas o corrigiram para ter um comportamento mais razoável, adicionando ainda mais variação.
Stéphane Chazelas

3

Sim, são possíveis shells de login não interativos

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

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

$

Isso é semelhante a este simplificado: su -c 'echo hello' -. Que, para testar o que precisamos, deve ser escrita como: su -c 'echo $0 $-; shopt -p login_shell' -para obter esta resposta confirmando (codificado entre aspas C): $'/etc/profile read \n -su hBc \n shopt -s login_shell'. Isso confirma que um shell não interativo de logon foi excutado e que, no processo, / etc / profile foi lido. Obrigado.

0

É possível ter um shell de logon não interativo (não chamado com --login ou -l)?

SIM.

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

No entanto, observe que /etc/profilenão seria usado para um shell de login não interativo, a menos que o --loginargumento seja fornecido.

Um idioma comum que chama um shell de logon não interativo é:

$ su - someuser -c somecommand

Mas isso sofre o fato de que /etc/profilenão é executado.

É possível alterar esse comportamento, mas envolve a personalização do código-fonte do Bash no tempo de compilação, descomentando uma opção encontrada em 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 pesquisei essa suanomalia , descobri que outras conchas incluem zshe dashnão têm essa discrepância.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.