¿Qué es la extensión de archivo Bash?

82

He escrito un script bash en un editor de texto, ¿qué extensión guardo mi script para que pueda ejecutarse como un script bash? He creado un script que, en teoría, debería iniciar un servidor ssh. Me pregunto cómo hacer que se ejecute el script una vez que hago clic en él. Estoy ejecutando OS X 10.9.5.

Amedeo
fuente
4
El script de Shell no requiere ninguna extensión en particular. Simplemente ejecútelo comobash myscript
anubhava
7
Por lo general .sh, pero no se requiere que la extensión exista en absoluto. Linux no es Windows. El programa que interpretará su guión se determina en su primera línea, que debería ser #!/bin/bash. Incluso puede incluir parámetros.
Havenard
1
@anubhava ¿Cómo conseguiría que se ejecutara mi script si solo hiciera doble clic en él y no escribiera "bash myscript"?
Amedeo
2
@Amedeo que encabezaría su archivo con la línea #!/bin/bash.
Havenard
4
Sin extensiones: extensiones de nombre de comando consideradas dañinas .
gniourf_gniourf

Respuestas:

106

En desacuerdo con las otras respuestas, existe una convención común para usar una .shextensión para scripts de shell, pero no es una convención útil. Es mejor no utilizar ninguna extensión. La ventaja de poder decir que foo.shes un script de shell debido a su nombre es mínima y se paga con una pérdida de flexibilidad.

Para hacer que un script bash sea ejecutable, debe tener una línea shebang en la parte superior:

#!/bin/bash

y use el chmod +xcomando para que el sistema lo reconozca como un archivo ejecutable. Luego, debe instalarse en uno de los directorios enumerados en su $PATH. Si se llama al script foo, puede ejecutarlo desde un indicador de shell escribiendo foo. O si está en el directorio actual (común para los scripts temporales), puede escribir ./foo.

Ni el shell ni el sistema operativo prestan atención a la parte de extensión del nombre del archivo. Es solo parte del nombre. Y al no darle una extensión especial, se asegura de que cualquier persona (ya sea un usuario u otro script) que lo use no tenga que preocuparse por cómo se implementó, ya sea un script de shell (sh, bash, csh o lo que sea) , un script Perl, Python o Awk, o un ejecutable binario. El sistema está diseñado específicamente para que se pueda invocar un script interpretado o un ejecutable binario sin saber ni importar cómo se implementa.

Los sistemas similares a UNIX comenzaron con una interfaz de línea de comandos puramente textual. Posteriormente se agregaron GUI como KDE y Gnome. En un sistema de escritorio con GUI, normalmente puede ejecutar un programa (de nuevo, ya sea un script o un ejecutable binario), por ejemplo, haciendo doble clic en un icono que se refiere a él. Normalmente, esto descarta cualquier salida que el programa pueda imprimir y no le permite pasar argumentos de línea de comandos; es mucho menos flexible que ejecutarlo desde un indicador de shell. Pero para algunos programas (principalmente clientes GUI) puede ser más conveniente.

Las secuencias de comandos de shell se aprenden mejor desde la línea de comandos, no desde una GUI.

(Algunas herramientas hacen prestar atención a las extensiones de archivo Por ejemplo, los compiladores suelen utilizar la extensión para determinar el idioma que el código está escrito en:. .cPara C, .cpp. Para C ++, etc. Esta convención no se aplica a los archivos ejecutables)

Tenga en cuenta que UNIX (y los sistemas similares a UNIX) no son Windows. MS Windows generalmente usa la extensión de un archivo para determinar cómo abrirlo / ejecutarlo. Los ejecutables binarios deben tener una .exeextensión. Si tiene un shell similar a UNIX instalado en Windows, puede configurar Windows para que reconozca una .shextensión como un script de shell y usar el shell para abrirlo; Windows no tiene la #!convención.

Keith Thompson
fuente
2
Lo que pretendo es lo que mencionaste en el cuarto párrafo. Ejecutando mi script cuando se hace clic en un icono que se refiere a él.
Amedeo
2
@Amedeo: Entonces depende de su entorno de escritorio. En el que uso (Cinnamon en Ubuntu), al hacer doble clic en el icono de un script ejecutable me pide que lo ejecute en una terminal, lo muestre en un editor o lo ejecute sin una terminal. Lo hace independientemente de la extensión del archivo.
Keith Thompson
3
(Necro) Si omite la extensión, no podrá tener una carpeta con el mismo nombre. Entonces, por ejemplo, tiene deploy.sh(o deploy.bash) y una carpeta deploy, con lógica de implementación adicional. Si cambia el nombre del script a simplemente deploy, provocará un conflicto de nombre. Nombrar un archivo o carpeta de manera diferente perjudica la capacidad de administración y posiblemente la clasificación de archivos ( ls, en editores, etc.) Por supuesto, el shebang es, al final, el determinante. Pero las extensiones de archivo tienen el lugar que les corresponde.
Kafoso
2
@Kafoso: No creo que alguna vez haya sentido la necesidad de tener un script y un directorio con el mismo nombre. Si lo hiciera, podría llamar al directorio Deploy, aunque eso puede causar problemas al copiar a un sistema de archivos que no distingue entre mayúsculas y minúsculas.
Keith Thompson
2
En una Mac, hacer doble clic en los archivos siempre los abre en la aplicación predeterminada. Por lo tanto, es útil tener una .shextensión para que el script se abra en el editor que desee. Si desea ejecutar un script cuando haga doble clic, dele la .commandextensión y se ejecutará en Terminal cuando haga doble clic.
BallpointBen
17

No necesita ninguna extensión (o puede elegir una arbitraria, pero .shes una convención útil).

Debe comenzar su script con #!/bin/bash(la primera línea la entiende execve (2) syscall), y debe hacer que su archivo sea ejecutable por chmod u+x. así que si su script está en algún archivo $HOME/somedir/somescriptname.sh, debe escribir una vez

 chmod u+x  $HOME/somedir/somescriptname.sh

en una terminal. Vea chmod (1) para el comando y chmod (2) para el syscall.

A menos que esté escribiendo la ruta completa del archivo, debe colocar ese archivo en algún directorio mencionado en su PATH(consulte environment (7) & execvp (3) ), que puede establecer permanentemente en su ~/.bashrcsi su shell de inicio de sesión es bash)

Por cierto, podría escribir su script en algún otro idioma, por ejemplo, en Python comenzando con #!/usr/bin/python, o en Ocaml comenzando con #!/usr/bin/ocaml...

La ejecución de su script haciendo doble clic (¿en qué? ¡No dijo!) Es un problema del entorno de escritorio y podría ser específico del escritorio (puede ser diferente con Kde, Mate, Gnome, ... o IceWM o RatPoison). Quizás leer las especificaciones de EWMH podría ayudarlo a obtener una mejor imagen.

Quizás hacer que su script sea ejecutable con chmodpodría hacer que se pueda hacer clic en su escritorio (aparentemente, Quartz en MacOSX). Pero entonces probablemente deberías hacer que dé alguna retroalimentación visual.

Y varias computadoras no tienen escritorio, incluido el suyo cuando accede a él de forma remota con ssh .

No creo que sea una buena idea ejecutar su script de shell haciendo clic en. Probablemente desee poder dar argumentos a su script de shell (¿y cómo lo haría haciendo clic?), Y debería preocuparse por su salida. Si puede escribir un script de shell, puede utilizar un shell interactivo en una terminal. Que es la mejor y más natural forma de utilizar un script. Los buenos shells interactivos (por ejemplo, zsh o fish o quizás uno reciente bash) tienen funciones de autocompletado deliciosas y configurables y no tendrás que escribir mucho (aprende a usar la tabtecla de tu teclado). Además, los scripts y programas son a menudo parte de comandos compuestos (canalizaciones, etc.).

PD. Utilizo Unix desde 1986 y Linux desde 1993. Nunca inicié mis propios programas o scripts haciendo clic. ¿Por qué debería?

Basile Starynkevitch
fuente
3
Bien, he creado mi secuencia de comandos en un editor de texto. Guardo el archivo en mi escritorio. Cuando hago clic en mi script que está guardado en mi escritorio, quiero que realmente se ejecute al hacer clic en él.
Amedeo
6
No sé cuál es tu escritorio (KDE, Gnome, MATE, ...). Lo invito encarecidamente a usar la línea de comandos en una terminal, especialmente para ejecutar sus scripts (probablemente quiera darles algunos argumentos; ¿cómo lo haría en el escritorio?). Si puede codificar un script de shell, debería poder usar el shell de forma interactiva en una terminal
Basile Starynkevitch
2
Mi punto es que si está codificando un script de shell, debe tomar el hábito de usar una línea de comando en una terminal.
Basile Starynkevitch
2
Entiendo que es para un proyecto en el que estoy trabajando. Quiero que el script se ejecute una vez que se haga clic en él. Estoy tratando de evitar usar el terminal para ejecutar el script.
Amedeo
3
Usaría en chmod +xlugar de chmod u+x, a menos que haya una razón específica para restringir la ejecución al propietario.
Keith Thompson
2

Sé que esto es bastante antiguo ahora, pero siento que esto se suma a lo que pedía la pregunta.

Si está en una Mac y desea poder ejecutar un script haciendo doble clic en él, debe usar la .commandextensión. También lo mismo que antes, hacer que el archivo sea ejecutable con chmod -x.

Como se señaló anteriormente, esto no es realmente tan útil tbh.

w_jay
fuente
1

solo .sh.

Ejecute el script así:

./script.sh

EDITAR: Como dijo Anubhava, la extensión realmente no importa. Pero por razones organizativas, se recomienda seguir utilizando extensiones.

Marc Anton Dahmen
fuente
6
Si está ejecutando un script, generalmente no tiene por qué preocuparse en lo que está escrito. Un script bash y un ejecutable binario se ejecutan de la misma manera. Agregar un .shsufijo a un script ejecutable generalmente es un desorden inútil.
Keith Thompson
1
sí, pero como dije en mi edición, es una convención para organizar scripts, ¿no más?
Marc Anton Dahmen
4
Veo muchos scripts con una .shextensión (y menos con una .bashextensión), pero no estoy convencido de que sea útil en absoluto. Si le doy un nombre a un script foo.shy luego decido volver a implementarlo en Perl, puedo cambiar el nombre (y editar todo lo que lo usa) o dejarlo con una extensión engañosa. Si lo nombro foo, no tengo ese problema.
Keith Thompson
1

TL; DR: si el usuario (no necesariamente el desarrollador) del script está utilizando una interfaz GUI, depende del navegador de archivos que esté utilizando. El Finder de MacOS requerirá la .shextensión para ejecutar el script. Gnome Nautilus, sin embargo, reconoce los scripts correctamente distribuidos con o sin la .shextensión.

Sé que ya se han dicho varias veces las razones a favor y en contra del uso de una extensión en scripts bash, pero no tanto por qué o por qué no usar extensiones, pero tengo lo que considero una buena regla general.

Si usted es del tipo que entra y sale de bash y usa la terminal en general o está desarrollando una herramienta para otra persona que no usa la terminal, coloque una .shextensión en sus scripts de bash. De esa manera, los usuarios de ese script tienen la opción de hacer doble clic en ese archivo en un explorador de archivos GUI para ejecutar el script.

Si es del tipo que principalmente hace todo o la mayor parte de su trabajo en la terminal, no se moleste en poner ninguna extensión en sus scripts bash. No servirían para nada en la terminal, asumiendo que ya ha configurado su ~/.bashrcarchivo para diferenciar visualmente scripts de directorios.

Editar:

En el navegador de archivos Gnome Nautilus con 4 archivos de prueba (cada uno con los permisos otorgados para que se ejecute el archivo) con el comando bash estúpidamente simple para abrir una ventana de terminal ( gnome-terminal):

  1. Un archivo sin extensión con #!/bin/bashen la primera línea.

    Funcionó haciendo doble clic en el archivo.

  2. Un archivo con una .shextensión con #!/bin/bashen la primera línea.

    Funcionó haciendo doble clic en el archivo.

  3. Un archivo sin extensión con NO #!/bin/bashen la primera línea.

    Funcionó haciendo doble clic en el archivo ... técnicamente, pero la GUI no dio ninguna indicación de que fuera un script de shell. Dijo que era solo un archivo de texto sin formato.

  4. Un archivo con una .shextensión con NO #!/bin/bashen la primera línea.

    Funcionó haciendo doble clic en el archivo.

Sin embargo, como Keith Thompson, en los comentarios de esta respuesta, señaló sabiamente, confiar en el uso de la .shextensión en lugar del bash shebang en la primera línea del archivo ( #!/bin/bash) podría causar problemas.

Otro, sin embargo, recuerdo cuando anteriormente usaba MacOS, que incluso los scripts de bash correctamente shebanged (¿es una palabra?) Sin una .shextensión no se podían ejecutar desde la GUI en MacOS. Sin embargo, me encantaría que alguien me corrigiera eso en los comentarios. Si esto es cierto, probaría que hay al menos un explorador de archivos donde la .shextensión es importante.

Ryan Hart
fuente
¿Qué navegador de archivos GUI usa (o, más relevante, qué usan sus usuarios)? ¿Utiliza la extensión para decidir cómo ejecutar un script?
Keith Thompson
Bueno, la plataforma en la que tengo más experiencia es MacOS. En Finder, el usuario decide qué aplicaciones asociar con qué extensión. Ahora, estoy en Linux usando Gnome, pero no he podido experimentar cómo el navegador de archivos Nautilus de Gnome interactúa con archivos sin extensión todavía.
Ryan Hart
Si tiene un script ejecutable con un .shsufijo y #!/bin/bashen la primera línea, ¿se utilizará un navegador de archivos GUI shpara invocarlo (ignorando el shebang)? Si es así, eso podría causar algunos problemas. (La respuesta podría ser diferente para diferentes navegadores.)
Keith Thompson
Buenos puntos ahí. Actualicé mi respuesta anterior con algunas pruebas reales que hice hace un momento.
Ryan Hart
Interesante, pero ... Dijiste que "funcionó". Para cada uno de los 4 casos de prueba, sería bueno saber si lo invocó con /bin/basho /bin/sh(este último es el predeterminado para un script sin shebang). Si /bin/shes un enlace simbólico a /bin/bash(que es bastante común), puede saberlo observando el valor de $0. (Además, si se invoca bash cuando shse establece POSIXLY_CORRECT=y)
Keith Thompson,