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/bash
como primera línea para configurar el intérprete).
El sh
shell en Ubuntu esno bash
, pero un shell separado llamado dash
. dash
no 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 $UID
variable, 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 bash
con permisos de root, las cadenas serán iguales y el script funcionará.
Respuesta2
ComoMcLovin diceUID
, la variable de solo lectura (y ) configurada automáticamente EUID
es una característica especial debash
(y algunas otras conchas). No es estándar paraConchas estilo Bourney sh
no se puede suponer que establezca estas variables. En particular, sh
en Ubuntu es (actualmente, por defecto)dash
, que no los establece.
Tienes dos opciones:
- Haga que su script se ejecute en
bash
lugar desh
. - 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 .sh
sufijo:
- ¡Un
.sh
sufijo sugiere que es compatible consh
! - La mayoría de los scripts no reciben ningún sufijo, y tener un sufijo
.sh
o.bash
puede 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 .sh
sufijo 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/baz
es la primera palabra defoo-bar/baz qux
, mientras quespam\ ham
es la primera palabra despam\ ham eggs
porque el espacio anteriorham
se escapa con una barra invertida.cleanup
, si está en un directorio de suPATH
(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 nocleanup
tiene una #!...
línea hashbang o lo que dice esa línea:
sh cleanup
seguirá (intentando) ejecutarlosh
como intérprete.bash cleanup
seguirá (intentando) ejecutarlobash
como intérprete.
Esto se debe a que, en esos casos, en realidad está ejecutando el intérprete ( sh
o 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 sh
y bash
siguen 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 $UID
en 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 quecat
yls
, es razonable esperar que esté presente.
id
por sí solo genera una gran cantidad de información, pero id -u
solo 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. $UID
in bash
proporciona la ID de usuario real y id -u
realmente corresponde a bash
la de $EUID
. Si realmente desea el UID y no el EUID, utilice id -ru
.