¿Cuál es la diferencia entre ejecutar “ bash script.sh ” y “ ./script .sh ”?

Si script.sh es algo típico como

#!/bin/bash echo "Hello World!" 

¿Existe un forma de ejecutar el script? Creo que primero tienes que modificarlo para que se convierta en ejecutable.

Respuesta

Para tu script específico, cualquiera de las dos funcionará, excepto que ./script.sh requiere ejecución y bits legibles, mientras que bash script.sh solo requiere bits legibles.


La razón de la diferencia de requisitos de permisos radica en cómo se carga el programa que interpreta su script:

  • ./script.sh hace que su shell ejecute el archivo como si fuera un ejecutable.

El shell se bifurca y usa una llamada al sistema (por ejemplo, execve) para hacer que el sistema operativo ejecute el archivo en el proceso bifurcado. El sistema operativo verificará los permisos del archivo (por lo tanto, es necesario configurar el bit de ejecución) y reenviará la solicitud al cargador de programas , que examina el archivo. y determina cómo ejecutarlo. En Linux, los ejecutables compilados comienzan con un número mágico ELF , mientras que los scripts comienzan con un #! ( hashbang ). Un encabezado hashbang significa que el archivo es un script y debe ser interpretado por el programa que se especifica después del hashbang. Esto permite un script para decirle al sistema cómo interpretar el script.

Con su script, el cargador del programa ejecutará /bin/bash y pasará ./script.sh como argumento de la línea de comandos.

  • bash script.sh hace que su shell ejecute bash y pase script.sh como argumento de la línea de comandos

Entonces, el sistema operativo cargará (sin siquiera mirar script.sh, porque es solo un argumento de línea de comandos). El proceso bash creado interpretará el script.sh porque «se pasó como el argumento de la línea de comandos. Porque script.sh solo es leído por bash como un archivo normal, el bit de ejecución no es necesario.


Recomiendo usar ./script.sh sin embargo, porque es posible que no sepa qué intérprete requiere el script. Deje que el cargador del programa lo determine por usted.

Comentarios

  • Si el bit ejecutable no está configurado, también puede ejecutar el script haciendo ". ./script.sh"
  • @Dog Tienes razón. El punto es un atajo para el comando incorporado ' source ' , que ejecuta la secuencia de comandos en el proceso de bash actual. Por lo tanto, solo se requiere el bit legible.
  • @Dogeatcatworld si bien eso es cierto, ejecutar . ./script.sh no es lo mismo cosa como (o ./script.sh. Considere la secuencia de comandos #!/usr/bin/python -V < newline > print test.
  • Tenga en cuenta que la obtención de un script puede provocar la contaminación de la sesión interactiva. Por ejemplo, si un script cambia la variable de entorno PATH, este cambio afectará a los comandos que se ejecutan después de la fuente. Este enfoque realmente debería reservarse para situaciones en las que depende de los efectos secundarios (secuencias de comandos de configuración del entorno y similares). Para otras situaciones en las que no puede ' t cambiar los permisos, ejecutar el comando en la línea shebang, seguido del nombre del script es el enfoque más seguro.
  • Tenga en cuenta que , si obtiene un script en el directorio actual, no necesita usar ./ ; solo di . script.sh. Pero estoy de acuerdo con las personas que desalientan el uso del comando . en scripts que no estaban destinados a ser invocados de esa manera. Me sorprende que nadie haya mencionado eso, si la secuencia de comandos contiene exit comandos y usted la obtiene, podría cerrar la sesión. Un problema menos grave sería si el script ejecuta un cd, ya que eso también afectaría al shell principal (interactivo).

Answer

bash script.sh invoca la secuencia de comandos directamente usando bash.
./script.sh está usando shebang #!/bin/bash para determinar cómo ejecutar.

Si realmente quiere saber, qué binario se ejecuta si hace un bash script.sh podría averiguarlo con which bash.

Entonces, en su ejemplo, no hay diferencia. Sí, tienes que chmod +x script.sh para poder ejecutarlo directamente a través de ./script.sh.

Comentarios

  • Bueno, no hay diferencia asumiendo que /bin/bash es el primer bash en su $PATH.
  • Usted ' tiene razón. Y el shebang #!/bin/bash solo funciona si hay un /bin/bash
  • Bash (versión 4.2.37) en mi el sistema ejecuta scripts incluso sin el bit de ejecución establecido. ¿Por qué dice que se requiere un bit de ejecución?
  • Sí, el bit de ejecución solo se necesita invocando a través de ./script.sh.

Respuesta

Cree un archivo Delete_Self.sh como este:

 #!/bin/rm echo I am still here! 

Ejecute esto script como sh Delete_Self.sh verá «¡Todavía estoy aquí!»

Hágalo ejecutable y ejecútelo como ./Delete_Self.sh verá que no se repite nada, mientras que el archivo Delete_Self.sh desapareció.

Entonces, la diferencia es que:

  • bash script.sh ignorará el #! línea, porque bash está especificado como el programa para ejecutar script.sh.
  • ./script.sh leerá el #! línea para determinar el programa a ejecutar script.sh.

Comentarios

  • +1 para el buen ejemplo

Respuesta

Además de las otras respuestas, conocer la diferencia entre ejecutar un script a través de ./script.sh (i) y source ./script.sh (ii) son útiles: la versión (i) crea un nuevo shell en el que ejecutar el comando, mientras que (ii) lo ejecuta en el shell actual, lo que puede ser obligatorio si el ejecutable cambia las variables de entorno que deben conservarse después de que el ejecutable sale. Por ejemplo, para activar un entorno de Python Conda se debe utilizar lo siguiente:

source activate my_env 

N.B. Otra alternativa a source que puede encontrar es el . incorporado, es decir,

. activate my_env 

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *