O shell tem a mesma entrada padrão, saída padrão e erro padrão de qualquer outro comando?

O shell tem a mesma entrada padrão, saída padrão e erro padrão de qualquer outro comando?

O bash, por exemplo, está localizado em /bin/bash, isso significa que é um comando e cada comando possui três (0,1,2) poros: entrada padrão, saída padrão, erro padrão.

Isso também é 100% verdadeiro para o shell ou há algo diferente desde o significado especial do shell como comando ou processo?

Responder1

É igual a qualquer outro programa. Isso permite redirecionar e canalizar a E/S como outros programas.

echo "cat filename" | bash

executará o cat filenamecomando quando bashler sua entrada padrão do pipe.

bash -c "echo foo" > filename

executará o echo foocomando e a saída será redirecionada para o arquivo.

No Unix, não há nada de "especial" no shell. É apenas um programa comum cujo objetivo principal é executar outros programas.

Responder2

Vamos diferenciar algumas terminologias:

Acomandoé o que você digita em seu shell. Pode ser umapelidoou umfunção shell, ou pode referir-se a umarquivo executável.

Umarquivo executáveltalvez umexecutável binário(ou seja, aquele que contém código de máquina diretamente) ou umroteiro. Os scripts incluem scripts bash, scripts sh, scripts perl, scripts awk, scripts sed, scripts python, etc. al.

Os primeiros dois bytes do seu script (se for executado diretamente como um arquivo executável) devem ser #!, que é o "número mágico" que sinaliza ao seu kernel para ler mais bytes até que uma nova linha seja lida, interprete esses bytes como um caminho para umexecutável binário, possivelmente com um único argumento separado por espaço em branco (por exemplo #!/bin/awk -f), e executequeexecutável binário, com o caminho para o próprio script passado como argumento.

Em última análise, a única coisa que o kernel pode realmente executar é o código de máquina, ou seja, um executável binário. Executáveis ​​binários como sh, bash, perl, python, awk, et. al. são chamadosintérpretes. Eles interpretam um script e executam suas instruções. Mas eles devem existir no próprio código de máquina para serem executados.

Quando um programa (executável binário) é realmente executado pelo kernel, ele existe como umprocesso. Um executável binário é apenas um arquivo contendo instruções. Aprocessoé uma "instância em execução de um programa"; mais especificamente, é uma abstração embutida no kernel que possui memória associada, variáveis ​​de ambiente, um ID de processo (PID),descritores de arquivoque pode ser usado para entrada e saída e outros atributos. Você pode executar um arquivo executável mais de uma vez "simultaneamente" (não literalmente simultaneamente em uma máquina de núcleo único, mas devido à maneira como o kernel aloca os ciclos de CPU, ele iráparecersimultâneo) e cada instância em execução será um processo diferente, mesmo que sejam todas instâncias do mesmo programa.

0, 1 e 2 – entrada padrão, saída padrão e erro padrão – sãodescritores de arquivo. Na verdade, é apenas por convenção que eles existem. Você pode criar um programa usando C que iniciará (executará) outros programas (executará vários executáveis ​​binários) sem fornecer a eles esses descritores de arquivo. No entanto,como todos os programas padrão são escritos assumindo a disponibilidade dos descritores de arquivo 0, 1 e 2, você provavelmente não obterá nada além de erros (na maioria dos casos) e os programas não funcionarão corretamente.

Para realmente entender isso completamente, você deve entendercomo um processo surge. Isto é um pouco como o milagre do nascimento. ;) Todos os processos devem ser iniciados poroutroprocesso. Sem se preocupar em como o primeiro processo é iniciado ao inicializar o sistema, o processo com PID 1 é chamado de "init" e inicia os demais processos básicos que seu sistema operacional precisa para funcionar.

A forma como um processo inicia outro processo ocorre em duas etapas básicas:garfoeexecutivo. Ambas são chamadas de sistema, ou seja, são ações/solicitações que o processo enviapara o núcleoque apenas o kernel pode realmente cumprir.

"Fork" significa (em poucas palavras), "kernel, por favor, faça uma cópia minha." ("Eu" sendo um processo em execução.) O kernel faz uma cópia completa do processo - seus descritores de arquivo, memória, estado de execução (onde está ao seguir as instruções que compõem o programa do qual é uma instância), variáveis ​​de ambiente e assim por diante. Portanto, é um “clone” do processo. Agora, como você pode diferenciar o original da cópia? Apenas por uma coisa: o status de retorno da forkchamada do sistema. O processo filho obtém “0” (sucesso) e o processo pai obtém o PID do processo filho recém-criado. Assim, ao inspecionar esse status de retorno, cada processo pode descobrir o que deve fazer agora (porque lembre-se, eles estão seguindo o mesmo conjunto de instruções!).

"Exec" é na verdade "execve()". Em poucas palavras, ele pergunta ao kernel, "kernel, por favorsubstituireu (sou um processo) com uma instância do programa especificado no arquivo ______." E o programador também especifica oargumentosque o novo processo terá, e oambiente(matriz de variáveis ​​de ambiente) que ele terá.

Então, quando você digita um comando no shell, o que realmente acontece (na maioria das vezes, ignorando casos especiais, como comandos internos do shell como cd) é que o seu shell (que é um processo em execução)garfos,e entãoexecutivoso comando que você especificou.

Se você fez o redirecionamento de saída ou entrada como /bin/echo hello > /dev/null, então o processo filho bifurcadoantes de execfazer ecoajustará seus descritores de arquivo de acordo, de modo que o descritor de arquivo 1 (neste exemplo) esteja vinculado ao /dev/nullinvés do seu terminal ou onde quer que estivesse antes.

Então, sim, qualquer instância em execução do arquivo executável /bin/bashespera ter disponível um descritor de arquivo 0 a partir do qual pode ler a entrada, um descritor de arquivo 1 no qual pode gravar a saída e um descritor de arquivo 2 no qual pode ler e gravar erros. mensagens e entrada/saída semelhantes.

informação relacionada