linux - hacer - scripts bash ejemplos
¿Por qué/bin/sh se comporta de manera diferente a/bin/bash incluso si uno apunta al otro? (4)
Mientras estaba jugando en mi caparazón investigando la respuesta a esta pregunta , noté que, aunque /bin/sh
apuntaba a /bin/bash
en mi sistema, los dos comandos se comportan de manera diferente. En primer lugar, la salida de
ls -lh /bin/sh
es:
lrwxrwxrwx 1 root root 4 Apr 22 2013 /bin/sh -> bash*
Sin embargo, invocando el siguiente comando a través de /bin/sh
:
/bin/sh -c "script.sh 2> >( grep -v FILTER 2>&1 )"
devuelve este error:
/bin/sh: -c: line 0: syntax error near unexpected token ''>''
/bin/sh: -c: line 0: ''script.sh 2> >( grep -v FILTER 2>&1 )''
Mientras ejecuta el mismo comando a través de /bin/bash
:
/bin/bash -c "script.sh 2> >( grep -v FILTER 2>&1 )"
se ejecuta con éxito, aquí está el resultado:
This should be on stderr
Como referencia, aquí está el contenido de script.sh
:
#!/bin/sh
echo "FILTER: This should be filtered out" 1>&2
echo "This should be on stderr" 1>&2
echo "FILTER: This should be filtered out" 1>&2
¿Por qué las dos invocaciones se comportan de manera diferente?
Del manual de referencia de Bash :
Si Bash se invoca con el nombre sh, intenta imitar el comportamiento de inicio de las versiones históricas de sh lo más fielmente posible, al mismo tiempo que se ajusta al estándar POSIX.
Invocar bash como sh
hace que ingrese al modo posix después de leer los archivos de inicio que normalmente leería (a diferencia de los archivos de inicio que un POSIX sh leería). Bash tiene muchos modos de invocación diferentes. Puede obtener más información sobre estos modos en la sección INVOCATION
del manual. Aquí hay algunos detalles sobre el modo POSIX.
Modo POSIX
Este modo significa que bash intentará, en varios grados, ajustarse a las expectativas de POSIX. Como se explica here , bash tiene algunas invocaciones diferentes para este modo, con implicaciones ligeramente diferentes:
-
sh
: Bash ingresa al modo POSIX después de leer los archivos de inicio. -
bash --posix
: Bash ingresa al modo POSIX antes de leer los archivos de inicio. -
set -o posix
: Bash cambia al modo POSIX. -
POSIXLY_CORRECT
: si esta variable está en el entorno cuando se inicia bash, el shell ingresa al modo posix antes de leer los archivos de inicio, comobash --posix
. Si se establece mientras bash se está ejecutando, comoset -o posix
.
Porque el bash
binary comprueba cómo se invocó (a través de argv[0]
) y entra en un modo de compatibilidad si se está ejecutando como sh
.
bash
mira el valor de $argv[0]
(bash se implementa en C) para determinar cómo se invocó.
Su comportamiento cuando se invoca como sh
se documenta en el manual :
Si Bash se invoca con el nombre
sh
, intenta imitar el comportamiento de inicio de las versiones históricas desh
más fielmente posible, al mismo tiempo que se ajusta al estándar POSIX.Cuando se invoca como un shell de inicio de sesión interactivo o como un shell no interactivo con la opción
-login
, primero intenta leer y ejecutar comandos desde/etc/profile
y~/.profile
, en ese orden. La opción--noprofile
se puede usar para inhibir este comportamiento. Cuando se invoca como un shell interactivo con el nombresh
, Bash busca la variableENV
, expande su valor si está definida y usa el valor expandido como el nombre de un archivo para leer y ejecutar. Como un intérprete de comandos invocado comosh
no intenta leer y ejecutar comandos desde ningún otro archivo de inicio, la opción--rcfile
no tiene ningún efecto. Un shell no interactivo invocado con el nombresh
no intenta leer ningún otro archivo de inicio.Cuando se invoca como
sh
, Bash entra al modo POSIX después de leer los archivos de inicio
Hay una larga lista (actualmente 46 elementos) de cosas que cambian cuando bash
está en modo POSIX, documentado aquí .
(El modo POSIX es probablemente útil sobre todo como una forma de probar scripts para portabilidad a shells que no son bash
).
Incidentalmente, los programas que cambian su comportamiento dependiendo del nombre bajo el cual fueron invocados son bastante comunes. Algunas versiones de grep
, fgrep
y egrep
se implementan como un único ejecutable (aunque GNU grep
no lo hace). view
es típicamente un enlace simbólico a vi
o vim
; invocándolo como view
hace que se abra en modo de solo lectura. El sistema Busybox incluye una cantidad de comandos individuales que son todos enlaces simbólicos al ejecutable master busybox
.