¿Zsh respeta shebang bin/sh para que se pueda usar dash?

¿Zsh respeta shebang bin/sh para que se pueda usar dash?

Tengo un script simple que involucra un forbucle desde bash que estoy tratando de hacer funcionar en zsh. Supuse que el shebang garantizaría que se usara un shell compatible con POSIX (en mi sistema que tengo /bin/sh -> dash*) para que no hubiera ningún problema.

Script MWE donde ITEMSen realidad es la salida de un comando que enumera paquetes, por ejemplo 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

Este es el resultado cuando intento ejecutar el script en 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

Cuando lo ejecuto en una terminal bash, funciona bien. Creo que he entendido mal cómo interpreta el tinglado zsh. ¿Alguien puede explicarme cómo se debe usar de manera que cuando ejecuto source scratch.shtenga . ./scratch.shel mismo resultado que si lo hubiera ejecutado sh scratch.sh? Sé que podría modificar mi script de bucle for para que sea compatible zshy bashde forma nativa, pero quiero usarlo, /bin/sh -> dashasí que siempre estoy usando un shell compatible con posix y no tengo que preocuparme por bashisms o zshisms.

Disculpas si esta es una pregunta básica, busqué zshy posixshebang pero no encontré una pregunta similar.

Respuesta1

El shebang solo tiene efecto si ejecuta el script directamentesin especificar como ejecutarlo; es decir, con algo como ./scratch.sho /path/to/scratch.sho colocándolo en un directorio en tu PATHy simplemente usando scratch.sh.

Si lo ejecuta usando algún otro comando, eso controla lo que se hace con él (anulando el shebang). Si lo usa bash scratch.sh, se ejecuta bash; si lo usas zsh scratch.sh, se ejecuta zsh; si usa sh, se ejecuta en lo que sea que shesté en su sistema ( dashen su caso específico).

Si usa source scratch.sho . scratch.sh, se ejecuta enel caparazón actual, sea lo que sea. Ese es el propósito de los comandos .and source. Y nuevamente, aquí se ignora el asunto.

Respuesta2

No puedes hacer eso. . scripto source scriptsimplemente incluye script, no bifurca un shell estándar o no estándar separado para hacerlo. En cuanto a shebangs, porque zsh(cuandofuenteun guión en lugar deejecutarit) son solo comentarios.

Sin embargo, puedes indicar zsh(intentar) emular temporalmente un shell estándar. YMMV.

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

emulate which_sh -c strse evaluará strcon la emulación especificada temporalmente en vigor y, lo que es más importante, hará que se "pegue" a cualquier función definida durante la evaluación de str, lo que provocará que el modo de emulación se active automáticamente durante su ejecución.

información relacionada