¿Qué hay de malo en este guión?

¿Qué hay de malo en este guión?

Obtuve este script de esta guía: www.tldp.org/LDP/abs/abs-guide.pdf

LOG_DIR=/var/log
ROOT_UID=0
LINES=50
E_XCD=86
E_NOTROOT=87

if [ "$UID" != "$ROOT_UID" ]
then
echo "Must be root to run this script."
exit $E_NOTROOT
fi

if [ -n "$1" ]
then
lines=$1
else
lines=$LINES
fi

cd $LOG_DIR

if [ 'pwd' != "$LOG_DIR" ]
then
echo "Can't change to $LOG_DIR."
exit $E_XCD
fi

Ahora hice sudo su en la terminal y repetí $UID, lo que me da 0. Eso significa que mi condición if resulta ser falsa pero aún así recibo "Debe ser root para ejecutar este script". mientras ejecuta este script.

También en el guión original esto si la condición se dio como

if [ "$UID" -ne "$ROOT_UID" ]

pero recibí un error de número ilegal porque aparentemente -ne solo se usa para cadenas, así que lo cambié a! =.

Respuesta1

En lugar de ejecutarlo con

sh script.sh

ejecutarlo con

bash script.sh

(o agregue #!/bin/bashcomo primera línea para configurar el intérprete).

El shshell en Ubuntu esno bash, pero un shell separado llamado dash. dashno tiene tantas funciones como bash, lo que lo hace más eficiente, pero estas funciones faltantes a veces interrumpen los scripts destinados a bash. Una de esas características es la $UIDvariable, que esno definidaen dash.

Esto significa que cuando el script se ejecuta en dash, la comparación se convertirá en ["" != "0"], lo que se evalúa como verdadero sin importar qué usuario lo esté ejecutando. Sin embargo, si se ejecuta bashcon permisos de root, las cadenas serán iguales y el script funcionará.

Respuesta2

ComoMcLovin diceUID, la variable de solo lectura (y ) configurada automáticamente EUIDes una característica especial debash(y algunas otras conchas). No es estándar paraConchas estilo Bourney shno se puede suponer que establezca estas variables. En particular, shen Ubuntu es (actualmente, por defecto)dash, que no los establece.

Tienes dos opciones:

  1. Haga que su script se ejecute en bashlugar de sh.
  2. Cambie su script para que sea más portátil y no requiera bash.

Ejecutando su script conbash

No nos has dicho el nombre de tu guión (lo cual está bien). voy a llamarlocleanup, ya que ese es el nombre de un script similar en la guía con la que estás trabajando.

Tenga en cuenta en particular que soynollamándolo algo así como cleanup.sh. Esto se debe a que no recomiendo nombrarlo con un .shsufijo:

  • ¡Un .shsufijo sugiere que es compatible con sh!
  • La mayoría de los scripts no reciben ningún sufijo, y tener un sufijo .sho .bashpuede incluso interpretarse como una sugerencia de que su archivo es una "biblioteca" en lugar de un script de "nivel superior". Es decir, que proporciona código para que otros scripts lo obtengan (por ejemplo, con el .incorporado) en lugar de ejecutarlo directamente.

Sin embargo, incluir un .shsufijo no afectará de ninguna manera el comportamiento técnico de su script. No existe ninguna ventaja o desventaja técnica asociada con hacerlo.

Agrega unlínea hashbangcomo la primera línea de su script:#!/bin/bash

Haz que tu script sea ejecutablecon .chmod +x cleanup

Ahora usted puedeejecuta tu scriptejecutando el comando:

  • ./cleanup, cuando está en el directorio actual. (Especialmente cuando se escriben guiones para educación, exploración, pruebas, diversión u otro uso limitado o único, esta es quizás la forma más común).

  • /path/to/cleanup, en general. Si la primera palabra de un comando contiene un, /se interpreta como una ruta a un archivo ejecutable. (Esa es la razón de la ./sintaxis anterior, ya que .significa el directorio actual).

    Porprimera palabraMe refiero al comando hasta pero sin incluir su primersin escaparespacio o tabulación:
    foo-bar/bazes la primera palabra de foo-bar/baz qux, mientras que spam\ hames la primera palabra de spam\ ham eggsporque el espacio anterior hamse escapa con una barra invertida.

  • cleanup, si está en un directorio de su PATH(y ningún directorio enumerado primero tiene un ejecutable con el mismo nombre y no está reemplazado por unshell incorporado,función, oalias).

Independientemente de si un guión o nocleanuptiene una #!...línea hashbang o lo que dice esa línea:

  • sh cleanupseguirá (intentando) ejecutarlo shcomo intérprete.
  • bash cleanupseguirá (intentando) ejecutarlo bashcomo intérprete.

Esto se debe a que, en esos casos, en realidad está ejecutando el intérprete ( sho bash) y pasando el nombre del script al intérprete para que lo ejecute. Muchos programas aceptan nombres de archivos para abrir en la línea de comando, y a los shells les gusta shy bashsiguen esta convención.

Cómo hacer que su script sea portátil

Si desea que su script sea portátil, la forma más sencilla es no usarlo $UIDen absoluto y, en su lugar, utilizar alguna función disponible para todos los shells estilo Bourne.

En general, no existe una función de shell incorporada para determinar la identificación del usuario. Pero puedes usarid. Este es un programa externo en lugar de un shell integrado, pero al igual quecatyls, es razonable esperar que esté presente.

idpor sí solo genera una gran cantidad de información, pero id -usolo proporciona la identificación de usuario efectiva.

Entonces, en lugar de if [ "$UID" != "$ROOT_UID" ], puedes usar:

if [ "$(id -u)" != "$ROOT_UID" ]

Técnicamente, esto no es equivalente. $UIDin bashproporciona la ID de usuario real y id -urealmente corresponde a bashla de $EUID. Si realmente desea el UID y no el EUID, utilice id -ru.

información relacionada