Forma correcta de distribuir scripts de shell


8

¿Cuál es la forma más adecuada de distribuir los scripts de shell si los comportamientos de los shells pueden modificarse sety, por lo tanto, son impredecibles?

Por ejemplo, rm *.txtno se ejecutaría como se esperaba en los entornos en los que set -fse ha ejecutado. ¿Cómo debo asegurarme de que rm *.txtelimine todos los archivos de texto en un directorio actual en cualquier entorno?

¿Cómo debo asegurarme de que los scripts de shell se ejecutarán como se esperaba antes de distribuirlos en general?


shell_state=$(set +o) ... guión ...eval "$shell_state"
mikeserv

Puede ejecutar esos comandos en la parte superior del script o modificarlos #!para especificar qué opciones de shell desea.
HalosGhost

Respuestas:


6

Los scripts de shell normalmente se tratan como si fueran los mismos que cualquier otro tipo de archivo ejecutable, como archivos binarios, scripts de Python, scripts de Perl o cualquier otro tipo de script. Tienen un shebang en la parte superior que dirige el núcleo para ejecutarlos a través del shell. Se espera que se invoquen de la misma manera que cualquier otro comando.

Como tal, se inicia un nuevo shell cada vez que se invoca el script, y cualquier configuración como la set -fpresente en el shell de invocación o en cualquier otra instancia de shell en el sistema es irrelevante.

Por supuesto, es posible que los usuarios obtengan su script en lugar de ejecutarlo, por ejemplo, así:

. /path/to/your/script

o para ejecutarlo en un shell que tiene configuraciones no predeterminadas como esta:

sh -f /path/to/your/script

pero esas no se consideran formas normales o invocando su script, y los usuarios que hacen eso deben esperar lo que obtengan como resultado.

Tenga en cuenta que hay algunos scripts que están destinados a ser obtenidos, no ejecutados, porque su propósito es hacer cosas como cambiar el cwd o establecer variables de entorno que deben reflejarse en el entorno del shell de abastecimiento, pero son minoritarias y generalmente se hace como parte de un protocolo acordado. Estos archivos se pueden considerar más como "complementos" para cualquier sistema del que esperan obtener, no tanto como scripts independientes. Por ejemplo, los archivos /etc/rc*.dcon nombres que terminan .shprovienen del subsistema de script de inicio, no se ejecutan, y está documentado que esto es lo que sucederá si coloca un archivo con ese nombre en/etc/rc*.dy cuando se hace, se hace a propósito. La convención de nombrar archivos destinados a ser obtenidos en lugar de ejecutarse de esta manera también se sigue en otro lugar, pero no universalmente.

Es cierto que los archivos destinados a ser obtenidos de esta manera tienen que cuidar qué configuraciones pueden estar presentes en el entorno de su interlocutor que puedan afectar el comportamiento del shell, pero entonces el protocolo acordado idealmente debería prometer un entorno de ejecución predecible.


1
zshtiene una característica que permite restaurar las opciones a un conjunto de conocimientos en un contexto local ( emulate -L zsh) que se usa ampliamente en todas las extensiones incluidas con zsh y escritas como código zsh. Vea cómo el sistema de finalización de bash falla miserablemente si configura algunas opciones como failglob.
Stéphane Chazelas

Algunos shells leen su archivo de personalización incluso cuando se invocan para interpretar los scripts. Es por eso que generalmente se usa en #! /bin/csh -flugar de, #! /bin/cshpor ejemplo.
Stéphane Chazelas

@ StéphaneChazelas Jaja, sí, de hecho. Por supuesto, eso es parte de por qué usar csh es una mala idea , ¿verdad? :-) Pero supongo que zsh también tiene eso, en forma de zshenv. ¡Cuidado con lo que pones zshenvpor esa razón!
Celada

@ StéphaneChazelas, por cierto, no es la primera vez que me enseñas algo que no sabía ( emulate -Len este caso) al comentar una de mis respuestas, y lo aprecio.
Celada

Bueno, ~/.zshenv(donde desea forzar la configuración (generalmente env vars) para todos los zsh's (interactivos o no) invocados bajo su nombre, y generalmente no se utilizan, excepto para solucionar algún otro problema que no sea zsh) está separado del ~/.zshrc(el shell de personalización), por lo que es una característica, no un error. (puede usar zsh -f) Un error es cuando algunos shells de bash no interactivos leen ~/.bashrc(como sobre ssh y tiene que agregar código para protegerse de eso), o algún bash interactivo (los de inicio de sesión) no lo leen (y de nuevo, debe agregar código en su ~/.bash_profilepara evitarlo).
Stéphane Chazelas
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.