outer.sh
:
ls -l /proc/$$/exe
coproc cat
./inner.sh
kill $!
inner.sh
:
ls -l /proc/$$/exe
set | grep COPROC || echo No match found
coproc cat
kill $!
Quando executo ./outer.sh
, isso é impresso:
lrwxrwxrwx 1 joe joe 0 Jun 16 22:47 /proc/147876/exe -> /bin/bash
lrwxrwxrwx 1 joe joe 0 Jun 16 22:47 /proc/147879/exe -> /bin/bash
No match found
./inner.sh: line 3: warning: execute_coproc: coproc [147878:COPROC] still exists
Já que COPROC
e COPROC_PID
não estão definidos na criança, como ele sabe sobre o do pai para poder me dar esse aviso?
Além disso, descobri que, se eu adicionar #!/bin/bash
ao topo de inner.sh
, ou se eu chamar bash ./inner.sh
em vez de apenas ./inner.sh
de outer.sh
, o aviso desaparecerá. Por que isso muda alguma coisa, já que está sendo executado com um subprocesso bash de qualquer maneira?
Um script sem shebang deve ser interpretado por um
sh
interpretador compatível com POSIX. Essa é realmente a maneira POSIX de escrever scripts POSIX, POSIX não especifica shebangs, embora na prática usar shebangs seja mais portátil / confiável, e aqui está um bom exemplo do porquê.O shell bash é um interpretador POSIX sh. bash (algumas versões e em algumas compilações personalizadas e em alguns ambientes) é na verdade o único shell FLOSS que eu sei que foi certificado como compatível ao executar como
sh
(não ao executar comobash
).Ao executar um script sem shebang, o bash, ao
execve()
retornar ENOEXEC e depois de verificar que não se parece com um arquivo binário, o interpreta em um filho dele, simulando uma execução tentando redefinir seu estado para o padrão.Isso significa, no entanto, que esse script, quando executado,
bash
é interpretado como um script bash em vez de um script POSIX sh, a menos quebash
esteja sendo executado no próprio modo POSIX (como quando invocado comosh
ele mesmo).Veja como
a
foi interpretado comobash
idioma (ignorando aliases) em vez dos idiomas sh quando invocado pelobash
.Veja como
bash
não executeish
para interpretar o script.O fato de você conseguir isso
warning: execute_coproc: coproc [147878:COPROC] still exists
é um bug quebash
não consegue redefinir seu estado corretamente.De qualquer forma,
coproc
não é uma palavra-sh
chave, portanto, não tem seu lugar em um script sem shebang.coproc
é dezsh
(enquanto coprocessos são de ksh), emborabash
a implementação de 's seja completamente diferente, então você deve ter um#! /bin/bash -
shebang aqui.Com
bash ./inner.sh
ou com um shebang, há uma execução adequada de uma nova instância do interpretadorexecve()
e limpa completa e corretamente a memória do processo.