Entenda o / etc / inittab
On Fevereiro 12, 2021 by admin Estou usando o seguinte /etc/inittab
arquivo (systemv):
# /etc/inittab: init(8) configuration. # $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $ # The default runlevel. id:5:initdefault: # Boot-time system configuration/initialization script. # This is run first except when booting in emergency (-b) mode. si::sysinit:/etc/init.d/rcS # What to do in single-user mode. ~~:S:wait:/sbin/sulogin # /etc/init.d executes the S and K scripts upon change # of runlevel. # # Runlevel 0 is halt. # Runlevel 1 is single-user. # Runlevels 2-5 are multi-user. # Runlevel 6 is reboot. l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 l3:3:wait:/etc/init.d/rc 3 l4:4:wait:/etc/init.d/rc 4 l5:5:wait:/etc/init.d/rc 5 l6:6:wait:/etc/init.d/rc 6 # Normally not reached, but fallthrough in case of emergency. z6:6:respawn:/sbin/sulogin S0:12345:respawn:/sbin/getty -L 115200 ttyS0
Para entender como as coisas realmente funcionam, ficarei grato se suas respostas a 1-3, você distinguirá entre duas situações:
- Estou conectado ao meu sistema usando uma porta serial.
- Eu tenho um pc desktop “normal”.
Perguntas:
-
Se eu adicionar outra linha getty, assim que o linux inicializar, verei dois terminais separados?
-
Se eu abrir várias linhas getty, como eu atribuí quais Getty executará meu comando
si::sysinit:/etc/init.d/rcS
e qual getty executará os outros comandos de script? (aqueles que executam scripts de acordo com o nível de execução do sistema)em outras palavras: no arquivo
/etc/inittab
– posso atribuir diferentes comandos a diferentes gettys? (quero dizer, aos terminais que serão abertos por esses gettys) -
o último script na pasta /etc/init.d/rc5 executado o seguinte comando:
su nobody -c /bin/sh
e a saída é:
sh: cannot set terminal process group (1618): Inappropriate ioctl for device sh: no job control in this shell sh-4.3$ whoami nobody
Então, verifiquei que não sou ninguém, mas por que escreve as duas primeiras linhas? também porque o prompt é sh-4.3 $ e não ninguém @ …
-
Estou usando uma conexão serial. Posso alterar o arquivo / etc / inittab e o último script que será executado pelo init a fim de:
- executar um programa antes de fazer o login como um usuário com poucos privilégios (o processo do init aguardará o término)
- assim que o programa sair do normal prompt de login no meu sistema
- qual é a melhor maneira de criar um usuário com poucos privilégios e deixá-lo executar este programa durante o processo de inicialização (se eu não quiser usar o usuário nobody)
Resposta
Pergunta 1:
Sim, adicionando mais getty
linhas, você pode obter mais terminais em paralelo. Apenas um getty
pode ser associado a um dispositivo de terminal por vez, portanto, apenas um getty
por porta serial é possível. Em um PC desktop normal, o kernel Linux define uma série de consoles virtuais, acessíveis usando as combinações de teclas Control + Alt + FX e correspondendo a /dev/ttyX
dispositivos (X = um número). A configuração exata pode variar entre as distribuições, mas geralmente nas distribuições principais, os primeiros 6 ou mais /dev/ttyX
dispositivos têm getty
s configurados para eles quando o sistema está funcionando normalmente. Você pode usar os comandos openvt
e deallocvt
para adicionar ou remover consoles virtuais e iniciar processos (que podem ser quaisquer processos, não necessariamente getty
s) neles.
/dev/tty0
é especial: refere-se a qualquer console virtual selecionado no momento. /dev/console
é um dispositivo especial semelhante, apontando para qualquer dispositivo TTY definido como o console do sistema em nível de kernel primário. Em sistemas desktop, é efetivamente um alias para /dev/tty0
por padrão, mas usando a opção de inicialização console=
, você pode alterná-lo para um serial porta. Por ex. algumas arquiteturas embutidas, pode ser uma porta serial por padrão. Utilitários como xconsole
também podem atuar como uma saída adicional para /dev/console
.
Na época em que os computadores eram grandes dispositivos com vários gabinetes em salas de computadores dedicadas, enviar uma mensagem para /dev/console
seria uma maneira de entrar em contato com o operador do sistema de plantão fisicamente perto do computador, o que pode ter sido útil para solicitações de, por exemplo, mudar fitas ou pacotes de disco. Em sistemas modernos, as mensagens enviadas especificamente para /dev/console
são geralmente mensagens de inicialização / desligamento ou, possivelmente, um canal de último recurso para alarmes urgentes sobre condições de falha que podem afetar o acesso à rede ou ao armazenamento ou mesmo envolvem um travamento do kernel: “uma pessoa encarregada do hardware físico precisa ver isso e os arquivos de log normais são inutilizáveis por algum motivo.”
Pergunta 2:
Receio que você tenha um conceito errado aqui. A linha sysinit
e outras /etc/inittab
linhas não estão associadas a getty
processos em tudo. Cada comando executado de inittab
, a menos que especificado de outra forma, tem sua entrada, saída e fluxos de erro padrão associados a /dev/console
.
As getty
linhas realmente especificam o dispositivo TTY que usarão e o processo getty
tem um código integrado que atribuirá esse dispositivo TTY para eles próprios e todos os seus processos filho, a menos / até que o usuário execute um shell e escolha redirecionar esses fluxos de alguma outra maneira.Isso e inicializar as configurações do dispositivo TTY são a maior parte do propósito de getty
“: exibir /etc/issue
e o prompt de login, aceitando o nome de usuário, definir a variável de ambiente TERM e iniciar a próxima etapa do processo de login TTY (geralmente /bin/login
mas personalizável) são apenas partes menores.
Observe que lá é uma convenção que para os dispositivos TTY, o campo de ID de dois caracteres na primeira coluna da linha inittab
deve corresponder ao nome do dispositivo TTY em questão após /dev/tty
prefixo, então /dev/ttyS0
receberá um ID de linha inittab de S0
, e assim por diante. Para coisas que não está necessariamente associado a qualquer TTY (ou apenas envia material de emergência para / dev / console se necessário), o ID pode ser qualquer coisa que não entre em conflito com os IDs de linha do dispositivo TTY.
(Voltar em o dia em que os terminais com conexão serial foram o não rm, obter as configurações do dispositivo TTY corretas para o terminal do outro lado da linha e redefinir esse terminal para um estado conhecido para login não eram tarefas triviais, pois havia muitos padrões de tipo de terminal concorrentes.)
Se você configurar uma linha inittab
para executar um script, poderá, por exemplo, ver se um determinado /dev/ttyX
console virtual dispositivo existe. Caso contrário, você pode usar openvt -c X <command>
para criar o console virtual e iniciar um comando nele; se o dispositivo de console virtual já existe, você pode simplesmente iniciar qualquer comando que quiser com entrada, saída e erro padrão redirecionados para ele. Por exemplo, você pode especificar uma linha inittab como esta:
6:345:respawn:/usr/local/sbin/myscript
e, em seguida, /usr/local/sbin/myscript
com algo assim ( isenção de responsabilidade: não testado, não tenho um sistema com SysVinit disponível no momento, fique à vontade para editar se você puder melhorar isso):
#!/bin/sh if [ -c /dev/tty6 ]; then exec <some command> </dev/tty6 >/dev/tty6 2>&1 else exec openvt -c 6 -w <some command> fi
respawn
na linha inittab
garante que o processo será reiniciado automaticamente se morrer por qualquer motivo. 345
é a lista de níveis de execução SysVinit em que este processo deve ser executado. Se você precisar que ele seja executado em todos os níveis de execução regulares, digite 12345
.
Observe, isto funciona como pretendido apenas se a linha inittab for colocada após a linha sysinit
, de modo que a inicialização de udev
pode ser considerada completa. você deseja fazer isso no início do processo de inicialização, talvez seja necessário cuidar da criação dos nós de dispositivo reais para dispositivos que já possuem drivers carregados primeiro; assim que o udev
estiver em execução, ele deve criar nós de dispositivo automaticamente conforme os drivers de dispositivo são inicializados.
Se estiver usando uma porta serial, o openvt
não se aplica.
Então, sim, você definitivamente pode anexar comandos diferentes a dispositivos TTY diferentes. Ajuda se os comandos tiverem recursos internos para isso, como os getty
s têm, mas você também pode fazer isso com scripts.
(Se você configurar algo mais complicado do que um simples tail -f
para ver permanentemente algum registro em um console virtual não utilizado, você deve ler man setsid
e veja se é aplicável ao que você está planejando.)
Pergunta 3:
Há mais para inicializar uma sessão TTY para um usuário não root específico do que apenas iniciar um shell com su
.
As mensagens de erro
sh: cannot set terminal process group (1618): Inappropriate ioctl for device sh: no job control in this shell
são provavelmente causados pelo shell sendo associado ao dispositivo /dev/console
em vez de um dispositivo TTY específico. Uma vez que /dev/console
é apenas um alias para o que quer que seja o console do sistema atual, ele não terá o conjunto completo de funções ioctl de controle de TTY disponíveis.
Se não houver script de login para atribuir um valor mais útil à variável de ambiente PS1
, o prompt padrão para /bin/sh
pode ser simplesmente sh-<version>$
.
Pergunta 4:
Sim, você pode. Você deve especificar o “último script” como uma linha do tipo wait
em inittab
e colocá-lo antes a getty
linha correspondente à sua linha serial.
Sem saber muito mais detalhes sobre o seu ambiente, será muito difícil dizer qual seria o melhor maneira de criar um usuário de baixo privilégio para esses fins.
Comentários
Resposta
-
Sim, assumindo a linha recebe um identificador único e a linha de terminal configurada está disponível:
S1:12345:respawn:/sbin/getty -L 115200 ttyS1
abrirá um terminal na porta serial conectada a
ttyS1
. -
As linhas em
inittab
não são sequenciais ou relacionadas a um login. Cada linha descreve uma ação a ser executada em um determinado conjunto de níveis de execução. Assim,si::sysinit:/etc/init.d/rcS
especifica queinit
deve ser executado/etc/init.d/rcS
ao lidar com a inicialização do sistema; isso acontece antes que os logins sejam possíveis. (Consulte ainittab(5)
página de manual para obter detalhes).Para atribuir comandos diferentes a
getty
s em terminais específicos, você configuraria agetty
invocação em si, por exemplo, alterando alogin
programa que inicia (a opção-l
na maioria dasgetty
implementações):S0:12345:respawn:/sbin/getty -L 115200 -l /bin/my-t0-login ttyS0 S1:12345:respawn:/sbin/getty -L 115200 -l /bin/my-t1-login ttyS1
-
/etc/init.d/rc 5
é executado antes que os logins sejam possíveis, e os programas que executa não estão conectados a um terminal (“corretamente”, o que é o quegetty
faz – abre o terminal para você e conecta os programas que inicia nele), portanto, quandosu nobody -c /bin/sh
é invocado, o o shell não encontra a configuração de terminal que espera e desativa o controle de trabalho como resultado. O promptsh-4.3$
é o prompt padrão do Bash 4.3 quando executado como/bin/sh
. -
Se o seu programa só deve ser executado quando um usuário inicia o login, você pode conectá-lo à sequência de login usada por
getty
; mas tal programa seria executado como root. Dependendo do que você deseja exatamente, provavelmente seria melhor usar um initscript em vez de/etc/inittab
personalização ousudo
e o scripts de inicialização do shell.
Comentários
- obrigado por sua repetição. Posso pedir um esclarecimento por smail em relação à seção 2? como posso editar o comando login para cada getty diferente?
- Feito, veja a atualização.
- obrigado! só para verificar se entendi bem: por padrão o processo getty executará o comando / bin / login que executa o processo responsável pelo login do sistema. Agora, o getty executará um comando diferente, cada comando que eu ‘ escolher, e não chamará o processo de login do sistema como antes … estou certo?
- Sim, isso mesmo. A chave é fazer com que
getty
abra o TTY para você; seu comportamento normal é aguardar um nome de login e, em seguida, executarlogin
, conectado ao TTY;login
aguarda a senha, verifica e inicia o shell, também conectado ao TTY. Se você substituir a partelogin
, precisará garantir que o programa de substituição se comporte comologin
. - Por exemplo, se eu quiser pular a fase de login – ser capaz de abrir meu sistema com o usuário root sem inserir nenhum nome de usuário ou senha. Posso usar: S0: 12345: respawn: / sbin / getty -L 115200 -l – / bin / sh ttyS0 ou usar: S0: 12345: respawn: / sbin / getty -L 115200 -l [my_script_path] ttyS0 e dentro o script i ‘ executará o comando – / bin / sh e outros?
Resposta
Só agora um segundo (long!) a resposta foi postada. Devo dizer que o primeiro explica muito bem. No momento, gostaria de comentar o ponto três: É menos uma questão de tempo, mas de processos controlando um tty “virtual real”, e não apenas um “dummy de console”.
Antes de iniciar um shell “com controle de trabalho”, você deve configurar, ou seja, abrir um ttyN. O comando “genérico” é getty
. Disso tty-algo que você obtém, pode iniciar um shell, não apenas depois disso.
É como tentar primeiro iniciar um gerenciador de janelas e depois o xorg, ao invés de “inicializá-los” junto com o xinit. Eu acho que. “líder da sessão”.
Por causa de
xx:12:...:program
e, ao contrário:
aa:1:...:pr_1 bb:1:...:pr_2
… você obtém uma relação N: M (você também obtém uma bagunça se abusar – muitos RLs, cada um com muitos progs diferentes). Você pode ir longe com isso, mas desde sempre diferentes tipos de RC- “padrões” assumiram o controle. “Runcoms”. Com eles, o inittab parece simples, mas toda a complexidade está nesses scripts.
Mas o seu inittab parece simples e correto – apenas o último comentário e a entrada “z6” …
Talvez seu “su nobody” só precise de um “getty … ttyN” antes / por perto. su
em vez de login
, e nenhum reaparecimento. Deve pelo menos apresentar outra mensagem de erro diferente de “inapropriado”.
Conclusão (depois de ler a 2ª resposta): Você não precisa de um sistema init.d
complicado, o inittab bruto é flexível o suficiente. Só precisa obter o conceito e os detalhes corretos.
Você pode configurar três níveis de execução: um com ttyNs, um com ttySN e um RL que inicia ambos. É um parâmetro de inicialização que você pode adicionar com o carregador de inicialização. Nível de execução “5” no seu caso é apenas o padrão. Você escolhe um kernel, uma raiz = e um nível de execução para iniciar.
A ação “respawn” é para o que o sysvinit era / é realmente necessário . Muito mais não funciona e menos seria possível implementar em um script. Mas se você sair (ou travar) o “último” nível de shell, você precisa de uma rede de segurança.
sysvinit pode até mesmo detectar um erro de configuração exibindo o erro “spawning muito rápido – ignorando por 5 minutos …”.
getty
é um processo; você está falando sobre um dispositivo TTY . O kernel abriu o primeiro para você e para os scripts de inicialização;/dev/console
é um alias para ” o primeiro dispositivo TTY que foi aberto e usado pelo kernel “. Se a sua conta de usuário tiver permissão para acesso de leitura + gravação a um dispositivo TTY, você pode simplesmente começar a usá-lo (não é necessáriogetty
), mas pode ser uma boa ideia definir o Variável TERM corretamente:TERM=linux top </dev/tty8 >/dev/tty8 2>&1 &
ouTERM=vt100 top </dev/ttyS1 >/dev/ttyS1 2>&1 &
iniciará o comandotop
no 8º console virtual ou a segunda porta serial.getty
processo nele, isso causará uma confusão de a saída de entrada &, pois os dois processos lutarão pela entrada e suas saídas serão misturadas. Osgetty
processos são iniciados apenas após/etc/init.d/rc 5
e quaisquer scripts iniciados por ele tenham terminado >