Cómo usar Bash para sh en Ubuntu

13

Estoy instalando un gran programa, que tiene sus recursos como un rpmarchivo. Se atascó en la línea de

#!/bin/sh
SCITEGICPERLBIN=`dirname $0`
SCITEGICPERLHOME=`dirname $SCITEGICPERLBIN`
if [ $SCITEGICPERLHOME == "." ]

Aparentemente, shtrabaja bashen Red Hat Linux con esta sintaxis, pero da el error de unexpected operatoren Ubuntu.

No puedo cambiar el script a bashcomo el script proviene del rpmpaquete. Puedo extraer y volver a rpmempaquetar el paquete, pero puede haber muchos de estos scripts.

¿Hay alguna manera de cambiar el valor predeterminado de shell para tratar #!/bin/shcomo basho cualquier otra cosa que pueda manejar el [operador?

Googlebot
fuente
55
Lo único malo es lo ==que debería ser =. Eso, y que las expansiones variables deben ser citadas dos veces.
Kusalananda
44
[no es un operador, sino un comando incorporado que se llama test. El operador inesperado es ==y esto debe reemplazarse =porque no es compatible con POSIX.
schily
La segunda cosa que está mal es que $SCITEGICPERLHOMEdebería citarse.
l0b0
12
Debería quejarse con el autor del programa. Si usan #!/bin/sh, deben asegurarse de que solo usen las funciones de shell POSIX, no bashextensiones. Este programador es muy descuidado. Debería arreglar su código o usarlo #!/bin/bash.
Barmar
Para las personas que se preguntan sobre otros temas similares, aquí hay una lista de " Bashismos ". También vea esta pregunta .
Capitán Man

Respuestas:

21

Existen múltiples programas que implementan el lenguaje de /bin/sh. En Ubuntu, /bin/shes dash, que está diseñado para ser rápido, para usar una pequeña cantidad de memoria, y no admite mucho más que el mínimo esperado /bin/sh. En RHEL, /bin/shes bash, que es más lento y usa más memoria pero tiene más funciones. Una de estas características es el ==operador de la [sintaxis condicional. Dash admite [, que es una característica básica de sh, pero no tiene el ==operador que es una extensión bash (y ksh y zsh).

Puede cambiar su sistema para usar bash. En Ubuntu, /bin/shes un enlace simbólico a dash. En su lugar, puede convertirlo en un enlace simbólico bash. Las versiones actuales de Debian y Ubuntu (y derivados) hacen de esta una opción de instalación de dash. Para cambiarlo, ejecuta

sudo dpkg-reconfigure dash

y responda "sí" para mantener el guión como /bin/sho "no" para cambiar a bash.

Puede mantener bash como /bin/sh, pero hará que su sistema sea un poco más lento. Incluso es concebible que algún script del sistema sea incompatible con bash, aunque eso es poco probable ya que bash es principalmente un superconjunto de guiones.


Para las distribuciones que no tienen una interfaz para elegir entre implementaciones /bin/sh, aquí le mostramos cómo cambiar a bash.

sudo ln -s bash /bin/sh.bash
sudo mv /bin/sh.bash /bin/sh

Mantenga una terminal abierta y verifique que aún pueda ejecutar algunos shscripts después de eso. Si estropea este comando, hará que su sistema sea inutilizable. (Por cierto, la razón por la que utilicé los múltiples comandos anteriores en lugar de la simple vista sudo ln -sf bash /bin/shes que ln -sfno es atómica. En el caso que es poco probable que su computadora se bloquee durante esta operación, necesitaría arrancar desde los medios de rescate para restaurarlo. Por el contrario, mves atómico).

Para restaurar el guión como /bin/sh :

sudo ln -s dash /bin/sh.dash
sudo mv /bin/sh.dash /bin/sh

Tenga en cuenta que si sh está /bin/bashpredeterminado en su distribución, cambiar a dash puede hacer que los scripts fallen, porque bash tiene muchas más funciones que dash. Las secuencias de comandos de Bash deberían comenzar con #!/bin/bash, y las secuencias de comandos que comienzan con #!/bin/shno deberían usar características específicas de bash, pero las distribuciones que se envían con bash /bin/shpueden usar características específicas de bash en #!/bin/shsecuencias de comandos que son específicas de esa distribución (está bien siempre que no se espere que los usuarios puede cambiar a guión como /bin/shy no hay expectativas de que estos scripts funcionen en otra distribución).

Gilles 'SO- deja de ser malvado'
fuente
En mi opinión no tan humilde, si algún script falla cuando /bin/shes Bash, es un error en el sistema (el paquete con el script) o en el modo de Bash sh. Como dice Stephen, el sistema permite explícitamente /bin/shvolver a Bash a través de dpkg-reconfigure. También se menciona como una posibilidad en el wiki de Ubuntu sobre este asunto: wiki.ubuntu.com/DashAsBinSh
ilkkachu
55
@ilkkachu Sí, si un script falla si /bin/shes bash, es un error. Sin embargo, ocurren errores. Recomiendo mantener el valor predeterminado si no es capaz y no está dispuesto a diagnosticar dichos errores porque otras personas lo han probado por usted. Utilicé dash como /bin/shantes tenía soporte oficial en Debian, pero este fue un riesgo que asumí, sabiendo que sería capaz de hacer frente si algo sucedía.
Gilles 'SO- deja de ser malvado'
Tenga en cuenta que los enlaces simbólicos anulados manualmente se restaurarán a la configuración que se almacene debconfla próxima vez que dashse actualice; Es cierto que esto no sucederá a menudo (si es que lo hace, en una versión dada) para sistemas que ejecutan Debian estable.
Stephen Kitt
36

Para cambiar sha bash(en lugar del dashpredeterminado), reconfigure dash(sí, es algo contra-intuitivo):

sudo dpkg-reconfigure dash

Esto le preguntará si desea dashser el shell predeterminado del sistema; responda "No" ( Tabentonces Enter) y bashse convertirá en el valor predeterminado ( es decir, /bin/sh apuntará a /bin/bash).

Stephen Kitt
fuente
1
Su solución es de hecho la más razonable, pero acepté otra respuesta debido a las descripciones detalladas que aclaran el problema. Perdón por cualquier inconveniente.
Googlebot
@Googlebot no necesita disculparse, elegir la respuesta aceptada es un privilegio del autor de la pregunta. Y obtuve una insignia de oro ;-).
Stephen Kitt