Para esta pergunta, vamos considerar um script shell bash, embora essa pergunta deva ser aplicável a todos os tipos de script shell.
Quando alguém executa um shell script, o Linux carrega todo o script de uma só vez (talvez na memória) ou lê comandos de script um por um (linha por linha)?
Em outras palavras, se eu executar um script de shell e excluí-lo antes que a execução seja concluída, a execução será encerrada ou continuará como está?
linux
shell
shell-script
Usuário Registrado
fonte
fonte
Respostas:
Se você usar,
strace
poderá ver como um script de shell é executado quando é executado.Exemplo
Digamos que eu tenho esse script de shell.
Executando usando
strace
:Uma olhada no
strace.log
arquivo revela o seguinte.Depois que o arquivo é lido, ele é executado:
No exposto acima, podemos ver claramente que o script inteiro parece estar sendo lido como uma única entidade e depois executado depois. Portanto, "apareceria" pelo menos no caso de Bash que ele lê o arquivo e o executa. Então, você acha que pode editar o script enquanto está em execução?
NOTA: Não! Leia para entender por que você não deve mexer com um arquivo de script em execução.
E quanto a outros intérpretes?
Mas sua pergunta está um pouco errada. Não é o Linux que está necessariamente carregando o conteúdo do arquivo, é o intérprete que está carregando o conteúdo, então depende muito de como o intérprete é implementado, se ele carrega o arquivo inteiramente ou em blocos ou linhas por vez.
Então, por que não podemos editar o arquivo?
Se você usar um script muito maior, notará que o teste acima é um pouco enganador. De fato, a maioria dos intérpretes carrega seus arquivos em blocos. Isso é bastante padrão com muitas das ferramentas do Unix, onde eles carregam blocos de um arquivo, processam e depois carregam outro bloco. Você pode ver esse comportamento com as perguntas e respostas de perguntas e respostas que escrevi há um tempo atrás
grep
, intituladas: Quanto texto o grep / egrep consome a cada vez? .Exemplo
Digamos que criamos o seguinte script de shell.
Resultando neste arquivo:
Que contém o seguinte tipo de conteúdo:
Agora, quando você executa isso usando a mesma técnica acima, com
strace
:Você notará que o arquivo está sendo lido em incrementos de 8 KB, portanto, o Bash e outros shells provavelmente não carregarão um arquivo por inteiro, em vez disso, eles serão lidos em blocos.
Referências
fonte
Isso depende mais do shell do que do SO.
Dependendo da versão,
ksh
leia o script sob demanda por um bloco de 8k ou 64k bytes.bash
leia o script linha por linha. No entanto, como as linhas de fato podem ter um comprimento arbitrário, ele lê cada 8176 bytes a partir do início da próxima linha para analisar.Isto é para construções simples, isto é, um conjunto de comandos simples.
Se comandos estruturados do shell forem usados ( um caso que a resposta aceita não considere ) como um
for/do/done
loop, umacase/esac
opção, um documento aqui, um subshell entre parênteses, uma definição de função etc. e qualquer combinação dos itens acima, os interpretadores do shell lêem até o final da construção para garantir primeiro que não haja erro de sintaxe.Isso é um tanto ineficiente, pois o mesmo código pode ser lido várias vezes, mas atenuado pelo fato de que esse conteúdo é normalmente armazenado em cache.
Qualquer que seja o interpretador do shell, é muito imprudente modificar um script do shell enquanto ele está sendo executado, pois o shell é livre para ler novamente qualquer parte do script e isso pode levar a erros inesperados de sintaxe, se estiver fora de sincronia.
Observe também que o bash pode falhar com uma violação de segmentação quando não é possível armazenar uma construção de script muito grande que o ksh93 pode ler perfeitamente.
fonte
Isso depende de como o intérprete executando o script funciona. Tudo o que o kernel faz é notar que o arquivo a ser executado começa com
#!
, essencialmente executa o restante da linha como um programa e fornece o executável como argumento. Se o intérprete listado lá lê esse arquivo linha por linha (como shells interativos fazem com o que você digita), é isso que você obtém (mas as estruturas de loop de várias linhas são lidas e mantidas para repetir); se o intérprete coloca o arquivo na memória, processa-o (talvez o compile em uma representação intermediária, como Perl e Pyton), o arquivo é lido na íntegra antes de executar.Se você excluir o arquivo enquanto isso, ele não será excluído até que o intérprete o feche (como sempre, os arquivos desaparecem quando a última referência, seja uma entrada de diretório ou um processo que o mantém aberto) desaparece.
fonte
O arquivo 'x':
A corrida:
IIRC, um arquivo não é excluído desde que o processo o mantenha aberto. A exclusão apenas remove o DIRENT fornecido.
fonte