Quando um shell é executado durante o processo de inicialização do linux?

3

Eu não entendo quando faz um shell, vamos dizer bash, execute, qual programa executa o bash inicialmente primeiro.

    
por Parimal N 06.03.2014 / 10:10

6 respostas

4

A seqüência de inicialização do linux / unix tem muitos estágios, e há muitas referências e respostas neste site que explicam os detalhes. Mas para resumir;

Eventualmente, o kernel é carregado com drivers para que o disco e os dispositivos possam ser usados, e então inicia o processo com um pid (id do processo) de 1.

Tradicionalmente, este programa era um programa chamado init , mas hoje existem vários programas mais recentes ( systemd ou upstart ). Depende da sua distribuição e versão, qual deles é usado.

Iniciar é um processo em camadas.

Existe um conceito de escalonamento dos níveis de execução (1,2,3,4,5,6 ...) e o programa de inicialização alternará entre esses níveis automaticamente ou em estágios (para que o usuário possa obter controle).

  1. sendo a etapa inicial (modo de usuário único),
  2. modo multiusuário,
  3. multi usuário com rede
  4. modo GUI ...
  5. .. 6., ...

Estes níveis de execução não são fixos em pedra, eles dependem da distribuição e do programa de inicialização sendo usados (init, systemd, ...) e convenção.

Os níveis também dependem de como o padrão de start-up / shutdown escalonado foi projetado. (pense, o linux é usado em roteadores, telefones android, servidores e desktops, todos com requisitos diferentes).

Para transgredir de um nível de execução para outro, vários outros programas (serviços), como ligação (para DNS), rede, roteamento, servidores da web, ... são iniciados ou interrompidos, e bash pode ser usado para executar um script específico que inicia ou interrompe um serviço.

Eventualmente, você precisa fazer o login, seja em um console ou em uma interface gráfica, e você pode solicitar seu nome de usuário e senha.

Vamos pegar uma rota simples e dizer que você está em um console não gráfico, e o programa login está solicitando sua autenticação. Quando você passar, ele irá ler qual shell está configurado para o nome de usuário digitado em /etc/passwd e iniciá-lo, com entrada e saída definidas para o seu console e então você tem o prompt e pode começar a fazer o seu trabalho. Então, neste cenário,

init starts -> login which starts -> bash

Assim, todo processo é filho do primeiro processo (pode ser mais preciso dizer que todo processo tem o pid 1 como ancestral). No exemplo acima, login irá exec do shell, substituindo o processo de login pelo bash, o id do processo não é alterado. Quando você olha com ps , parece que o bash foi iniciado pelo init porque seu pai pid é 1, mas havia uma cadeia de eventos.

Não há nada que esteja realmente impedindo pid 1 de começar o bash no console (se o pid 1 puder descobrir o que o console está nesse ponto) e isso se resume a como a sequência de inicialização foi projetada. (Eu tive que fazer isso uma vez, mas não é uma prática normal).

    
por 06.03.2014 / 12:41
1

Se você tiver pstree instalado, você pode fazer:

pstree  | less

e use / para procurar o programa que você está interessado ( bash ) você pode então ver o que os processos pai e filho para as tarefas específicas são (excerto):

     |-tmux-+-bash---python2.7---2*[{python2.7}]
     |      '-sh---x2vnc---x2vnc
    
por 06.03.2014 / 10:30
1

No Unix, o shell é apenas outro programa. Há ainda uma infinidade de conchas ao redor, atendendo às perversões particulares de diferentes usuários na área de interface de linha de comando. O POSIX exige que um determinado shell (essencialmente um shell Bourne despojado) esteja disponível.

Os shells Unix são muito mais do que apenas interpretadores de comandos, no entanto. Eles interpretam linguagens de programação bastante capazes. É comum escrever um script de comandos shell para automatizar tarefas repetitivas. Isso é obviamente lento, mas desde que isso seja usado apenas como cola para agrupar outros comandos para tarefas não freqüentes, isso não importa. A flexibilidade pode ser muito mais importante, pois o script pode ser editado na hora.

Como outras respostas explicam, iniciar um sistema é complexo, e partes dele podem se beneficiar do script de algumas tarefas. Como o shell é garantido para estar disponível, é uma escolha natural para isso. As tarefas executadas periodicamente (pelo cron ou similar) são normalmente escritas como scripts de shell.

Uma vez que o sistema ofereça um usuário para efetuar login, após verificar as credenciais, um programa é iniciado para interagir com eles. Que isso, por padrão, é o mesmo shell mencionado acima é incidental, certamente pode-se selecionar outro programa. Existem muitos shells alternativos, e outros programas podem fazer sentido em circunstâncias especiais.

    
por 06.03.2014 / 14:17
1

O shell é executado durante a inicialização somente se os shell scripts forem chamados. O sistema tradicional init é construído em torno de scripts de shell (cada serviço / daemon é iniciado a partir de um script de shell). A maioria dos serviços é iniciada quando o sistema entra no modo multiusuário. Algumas coisas podem começar antes (a montagem do sistema de arquivos pode envolver scripts de chamada).

No linux, os initsrcipts são executados por sh , que normalmente é um link para bash .

No entanto, systemd , que está começando a substituir init em muitas distribuições (até o debian fala em comutar). systemd foi projetado para não usar initscripts e, em vez disso, inicia os daemons e as montagens por si próprio, além de manter o controle sobre eles e reiniciá-los se eles falharem. É inteiramente possível que um systemd inicialize sem executar interpretadores de shell, embora você possa sempre ter um serviço que seja um script de shell sozinho.

É claro que o shell padrão do usuário é iniciado no login, mas é após o processo de inicialização. Se você inicializar em um gerenciador de exibição (a maioria das distribuições centradas no usuário faz isso por padrão), o shell pode nunca ser executado. Eles até mesmo disfarçam o emulador de terminal, de modo que é preciso cavar os níveis dos menus para chegar até ele.

Com um pequeno hack, você pode registrar todas as instâncias do bash que começam. Cuidado, é perigoso, você pode quebrar o sistema. Copie seu bash temporariamente de /bin/ para outro lugar ( /usr/local/bin é um bom lugar, porque vem mais tarde em $ PATH). Escreva um script de shell como este:

#!/usr/local/bin/bash
(/bin/date && echo "$$:$@") >> /root/bash_runs.log
exec /usr/local/bin/bash "$@"

Substitua o /bin/bash por esse script. Ele chama internamente o real bash, então este não é um loop infinito. Ele registra a data e o PID do processo (não use o registrador, o sistema de registro já pode ter iniciado). Você também verá quais scripts são executados.

Repito: não faça isso a menos que você entenda todos os passos. E não se esqueça de reverter todas as alterações depois de terminar.

    
por 06.03.2014 / 15:02
1

O primeiro e principal objetivo do kernel ao carregar é encontrar e chamar init - userspace. É improvável que seu initramfs seja nada mais do que uma imagem de disco do Linux contendo esse 'init' e quantos arquivos forem necessários para compactar na imagem por init para localizar e montar seu sistema de arquivos raiz real. Estas não são regras rígidas e rápidas, por si só, mas são o padrão de defacto.

O verdadeiro problema em responder a esta questão é que, embora init seja um shell e os poucos arquivos que o acompanham no initramfs são apenas scripts de shell e alguns módulos do kernel necessários para montar seu dispositivo root, ele certamente não t tem que ser. O kernel não se importa - só quer init .

Então, a resposta a essa pergunta, eu acho, é assim que você a configura para ser chamada.

MAIS ...

Você pode testar isso facilmente - inclua o shell de sua escolha na imagem do initramfs e adicione o parâmetro:

"init=/path/to/shell" 

para a linha de comando do kernel do seu gerenciador de inicialização. Desde que as dependências do seu shell sejam atendidas, a próxima inicialização deverá fornecer um prompt interativo no início do espaço do usuário.

Provavelmente, nem mesmo adicionar seu shell é necessário, já que há uma strong possibilidade de que seu init já seja uma sessão busybox com script e

"init=/bin/sh" 

também funcionará - embora eu espere que a parte "tão boa" seja discutível. Em qualquer caso, se você já se encontrou em um desses " prompts de recuperação de emergência " provavelmente foi apenas /bin/sh em initramfs , a menos que você use grub e seu kernel falhou em carregar totalmente, caso em que definitivamente não era.

Stephane comentários abaixo sobre a diferença entre init e init . É certamente verdade que uma vez que switchroot é chamado o próximo programa invocado é muito menos provável que seja um shell do que quando o kernel descompactou initramfs (que acontece se você fornecer um ou não, por sinal) e chamado %código%. E definitivamente o post sobre o qual ele comentou tinha muito menos a dizer sobre o assunto do que isso, mas naquele momento qualquer init chamado é a segunda string - é apenas userspace chamando userspace .

Isso é significativo, pois qualquer controle entregue é dado voluntariamente, geralmente em um shell script, e não é uma necessidade para a operação, assim como o handoff do kernelspace para userspace . Isso pode se manifestar de maneiras diferentes - como sua opção de nunca chamar init e executar o sistema operacional fora de switchroot , ou initramfs tendo que matar systemd no espaço de usuário inicial para que pode iniciar um novo processo udev como filho - mas espero agora tornar um pouco menos obscuro a verdade de que udev é sempre chamado apenas uma vez e qualquer programa chamado init chamado posteriormente está carregando apenas a init tocha depois que o processo inicial é transmitido.

Outra resposta aqui comenta que init é tradicional , mas é provável que seja algo mais hoje . Não estou certo de seguir, mas pelo que sei, init foi antes e ainda continua sendo o processo inicial do userspace chamado pelo kernel após o carregamento, como é evidenciado pelo init kernel parâmetro mencionado acima e, mais frequentemente, init= é um shell.

Para resumir, provavelmente é melhor não pensar em init como o nome de um programa, mas como o nome do init que especifica um programa executável ao qual o kernel se rende controle inicial do userspace como um todo.

    
por 13.04.2017 / 14:36
0

Resposta curta: Um shell é executado quando necessário e não antes.

Resposta mais longa:

O momento mais óbvio que o shell é executado é quando um usuário faz logon. O programa tty que manipula a sessão do usuário iniciará o shell.

Outra possibilidade é quando é necessário por um cronjob, se o cronjob estiver usando um script em vez de um binário.

E há também a possibilidade de que, para iniciar alguns serviços, o shell precise ser chamado para executar um script.

    
por 06.03.2014 / 13:57