O zsh respeita o shebang bin/sh para que o dash possa ser usado?

O zsh respeita o shebang bin/sh para que o dash possa ser usado?

Eu tenho um script simples envolvendo um forloop do bash que estou tentando fazer funcionar no zsh. Eu presumi que o shebang garantiria que um shell compatível com POSIX fosse usado (no meu sistema que tenho /bin/sh -> dash*), para que não houvesse problemas.

Script MWE onde ITEMSestá na verdade a saída de um comando que lista pacotes, por exemplo ITEMS=$(pip freeze):

#!/bin/sh

# ITEMS=$(pip freeze)  # Example of useful command

ITEMS="Item1
Item2
Item3"  # Dummy variable for testing

for ITEM in $ITEMS; do
    echo $ITEM
    echo Complete
done

Esta é a saída quando tento executar o script em zsh:

$ source scratch.sh
Item1
Item2
Item3
Complete  # Undesired

$ . ./scratch.sh
Item1
Item2
Item3
Complete  # Undesired

$ bash scratch.sh
Item1
Complete
Item2
Complete
Item3
Complete  # Desired

$ sh scratch.sh
Item1
Complete
Item2
Complete
Item3
Complete  # Desired

Quando eu executo em um terminal bash, ele funciona bem. Acho que entendi mal como o shebang é interpretado por zsh? Alguém pode me explicar como deve ser usado para que quando eu executo source scratch.shou . ./scratch.shtenha a mesma saída como se tivesse executado sh scratch.sh? Eu sei que poderia modificar meu script de loop for para ser compatível zshe bashnativo, mas quero usá-lo, /bin/sh -> dashentão estou sempre usando um shell compatível com posix e não preciso me preocupar com bashisms ou zshisms.

Peço desculpas se esta é uma pergunta básica, pesquisei zshe posixshebang, mas não encontrei uma pergunta semelhante.

Responder1

O shebang só tem efeito se você executar o script diretamentesem especificar como executá-lo; isto é, com algo como ./scratch.shou /path/to/scratch.shou colocando-o em um diretório no seu PATHe apenas usando scratch.sh.

Se você executá-lo usando algum outro comando, isso controla o que é feito com ele (substituindo o shebang). Se você usar bash scratch.sh, ele roda em bash; se você usar zsh scratch.sh, ele roda em zsh; se você usar sh, ele roda em tudo o shque estiver no seu sistema ( dashno seu caso específico).

Se você usar source scratch.shou . scratch.sh, ele será executado ema casca atual, seja lá o que é. Esse é todo o propósito dos comandos .e source. E, novamente, a coisa é ignorada aqui.

Responder2

Você não pode fazer isso. . scriptou source scriptsimplesmente inclui script, ele não cria um shell padrão ou não padrão separado para fazer isso. Quanto às coisas, porzsh (quando vocêfonteum roteiro em vez deexecutarisso) eles são apenas comentários.

Você pode instruir zsh(tentar) emular temporariamente um shell padrão. YMMV.

emulate sh -c '. ./scratch.sh'

emulate which_sh -c stravaliará strcom a emulação especificada temporariamente em vigor e, mais importante, fará com que ela "grude" em quaisquer funções definidas durante a avaliação do str, fazendo com que o modo de emulação seja ativado automaticamente durante sua execução.

informação relacionada