Dado que el archivo no es de ninguno de los tipos de ejecutables reconocidos por el sistema, y suponiendo que tenga el permiso para ejecutar ese archivo, la execve()llamada al sistema generalmente fallará con un error ENOEXEC( no ejecutable ).
Lo que sucede entonces depende de la aplicación y / o función de biblioteca utilizada para ejecutar el comando.
Puede ser, por ejemplo, un shell, la función execlp()/ execvp()libc.
La mayoría de las otras aplicaciones usarán cualquiera de ellas cuando ejecuten un comando. Invocarán un shell, por ejemplo, mediante la system("command line")función libc, que normalmente invocará shpara analizar esa línea de comando (cuya ruta se puede determinar en el momento de la compilación (como /bin/shvs /usr/xpg4/bin/shen Solaris)), o invocará el shell almacenado $SHELLpor ellos mismos como vicon su !comando, xterm -e 'command line'y muchos otros comandos ( su user -cinvocarán el shell de inicio de sesión del usuario en lugar de $SHELL).
En general, un archivo de texto sin shebang que no comienza #se considera un shscript. Sin shembargo, cuál es variará.
execlp()/ execvp(), al execve()regresar ENOEXECnormalmente invocará shen él. Para los sistemas que tienen más de uno shporque pueden ajustarse a más de un estándar, lo shque se determinará generalmente en el momento de la compilación (de la aplicación usando execvp()/ execlp()mediante la vinculación de un blob de código diferente que se refiere a una ruta diferente a sh). Por ejemplo, en Solaris, será /usr/xpg4/bin/sh(un estándar, POSIX sh) o /bin/sh(el shell Bourne (un shell anticuado) en Solaris 10 y versiones anteriores, ksh93 en Solaris 11).
Cuando se trata de conchas, hay mucha variación. bash, AT&T ksh, el shell Bourne generalmente interpretará la secuencia de comandos ellos mismos (en un proceso secundario a menos que execse use) después de haber simulado un execve(), que desarma todas las variables no exportadas, cierra todos los archivos close-on-exec, elimina todas las trampas personalizadas, alias, funciones ... ( bashinterpretará el script en shmodo). yashse ejecutará en sí (con shcomo argv[0]lo que en shmodo) para interpretarlo.
zsh, pdksh, ashCáscaras basados típicamente invocar sh(el camino de los cuales determina en tiempo de compilación).
Para cshy tcsh(y el shde algunos BSD anteriores), si el primer carácter del archivo es #, entonces se ejecutarán para interpretarlo, y de lo shcontrario. Eso se remonta a un tiempo anterior al shebang donde cshreconocía #como comentarios pero no el shell Bourne, por lo que #era una pista de que era un script csh.
fish(al menos la versión 2.4.0), solo devuelve un error si execve()falla (no intenta tratarlo como un script).
Algunos shells (como bashAT&T ksh) primero intentarán determinar heurísticamente si el archivo probablemente sea un script o no. Por lo tanto, es posible que algunos shells se nieguen a ejecutar un script si tiene un carácter NUL en los primeros bytes.
También tenga en cuenta que si execve()falla con ENOEXEC pero el archivo tiene una línea shebang, algunos shells intentan interpretar esa línea shebang ellos mismos.
Entonces, algunos ejemplos:
- Cuando
$SHELLes /bin/bash, xterm -e 'myscript with args'habrá myscriptinterpretado por bashen shmodo. Mientras que con xterm -e myscript with args, xtermse usará execvp()para que el guión sea interpretado por sh.
su -c myscripten Solaris 10 donde rootel shell de inicio de sesión es /bin/shy /bin/shes el shell Bourne lo habrá myscriptinterpretado el shell Bourne.
/usr/xpg4/bin/awk 'BEGIN{system("myscript")'en Solaris 10 lo tendrá interpretado por /usr/xpg4/bin/sh(lo mismo para /usr/xpg4/bin/env myscript).
find . -prune -exec myscript {} \;en Solaris 10 (usando execvp()) lo interpretará /bin/shincluso con /usr/xpg4/bin/find, incluso en un entorno POSIX (un error de conformidad).
csh -c myscriptlo interpretará cshsi comienza con #, de lo shcontrario.
Con todo, no puede estar seguro de qué shell se usará para interpretar ese script si no sabe cómo y por qué se invocará.
En cualquier caso, read -pes una bashsintaxis única, por lo que querrá asegurarse de que el script sea interpretado por bash(y evitar esa .shextensión engañosa ). O conoce la ruta del bashejecutable y usa:
#! /path/to/bash -
read -p ...
O puede intentar confiar en una $PATHbúsqueda del bashejecutable (suponiendo que bashesté instalado) usando:
#! /usr/bin/env bash
read -p ...
(se envencuentra casi en todas partes /usr/bin). Alternativamente, puede hacer que sea POSIX + Bourne compatible, en cuyo caso puede usar /bin/sh. Todos los sistemas tendrán a /bin/sh. En la mayoría de ellos será (en su mayor parte) compatible con POSIX, pero aún puede encontrar de vez en cuando un shell Bourne allí.
#! /bin/sh -
printf >&2 'Enter a user name: '
read user
printf '%s\n' "$user"