
Estoy leyendo el script bash y no entiendo qué sucede allí.
#!/bin/sh
[ x$1 = x ]
¿Qué está pasando en la segunda línea y qué [ x$1 = x ]
significa?
Respuesta1
Eso comprueba que $1
esté vacío, aunque debe estar entre comillas (idéntico a [ -z "$1" ]
). Algunos shells muy antiguos no manejaban adecuadamente las cadenas vacías, por lo que los escritores de scripts portátiles adoptaron este estilo de verificación. No ha sido necesario durante décadas, pero la gente todavía lo hace de esa manera porque todavía lo hace de esa manera.
Respuesta2
Los corchetes indican unaprueba, por lo que [ x$1 = x]
sin if
o algo similar no tiene sentido, aunque sintácticamente está bien.
Está destinado a evaluarse como verdadero si x$1
se expande a x
y falso en caso contrario, pero como no está entre comillas, si $1
es (por ejemplo) "hey x", el shell verá x = x
, por lo que esta construcción aún no es segura.
El propósito de la x = x
verificación es determinar si una variable está vacía. Una forma más común de hacer esto sería simplemente usar comillas:
if [ "$1" = "" ]; then
Los operadores de prueba Bash -z
también -n
se pueden usar, pero son menos portátiles a otros tipos de shells. 1
El motivo de las comillas, o x$1
, es para que el lado izquierdo no se expanda a nada, lo que sería un error sintáctico:
if [ = x ] # No good!
if [ "" = "" ] # Okay.
if [ x = x ] # Also okay.
1. En realidad, test
puede ser una utilidad independiente, pero la mayoría de los shells la implementan como incorporada; Comprueba la diferencia entre which test
y type test
. En GNU/Linux man test
se afirma que hace referencia a la utilidad integrada, pero si llama (por ejemplo) /usr/bin/test
, esa utilidad parece implementar las funciones documentadas en la página de manual, incluidas -z
y -n
.
Respuesta3
[ x$1 = x ]
Sólo tiene sentido en zsh
. Eso compara la concatenación de x
con el primer argumento del script x
. Entonces el [
comando devuelve verdadero si $1
está vacío o no se proporciona.
[ $1 = "" ]
No funcionaría porque, zsh
cuando una variable vacía no se cita en contextos de lista, se expande sin ningún argumento en lugar de un argumento vacío, por lo que si $1
no estuviera configurada o estuviera vacía, el [
comando solo recibiría como argumentos la cadena vacía [
. =
y ]
al cual no podía encontrarle sentido. [ -z "$1" ]
o [ "$1" = "" ]
estaría bien, como en los shells POSIX.
En shells tipo Bourne/POSIX, [ x$1 = x ]
no tiene sentido. Ese es el operador split+glob aplicado de alguna manera a la concatenación de x
y el primer argumento del script con la esperanza de que el resultado y =
y x
formen ]
una expresión de prueba válida para el [
comando.
Por ejemplo, si al script se le pasara un " = x -o x ="
argumento, [
recibiría esos argumentos: [
, x
, =
, x
, -o
, x
, =
, x
, ]
que [
se entenderían como comparar x
con x
y x
con x
y devolverían verdadero.
Si $1
fuera así "* *"
, entonces el shell pasaría al [
comando la lista de archivos en el directorio actual cuyo nombre comienza con x
(la expansión global de x*
), luego la lista de archivos no ocultos (expansión *
)... lo cual [
es poco probable que pueda para encontrarle algún sentido. Los únicos casos en los que eso tendría sentido es si $1
no contiene comodines o caracteres en blanco.
Ahora, lo que a veces encuentras es código como:
[ "x$1" = x ]
Se utiliza para comprobar si $1
está vacío o no configurado.
La forma normal de probar una variable vacía o no configurada es:
[ -z "$1" ]
Pero eso falla para algunos valores de $1
like =
en algunas implementaciones (no POSIX) [
como la incorporada en el shell Bourne como se encuentra /bin/sh
en Solaris 10 y anteriores o en algunas versiones antiguas dash
(hasta 0.5.4) o en sh
algunos BSD.
Esto se debe a que [
ve [
, -z
, =
y ]
se queja de que faltan argumentos para el =
operador binario en lugar de entenderlo como el -z
operador unario aplicado a la =
cadena.
De manera similar, [ "$1" = "" ]
falla en algunas implementaciones de [
if $1
is !
o (
.
En esos shell/ [
implementaciones:
[ "x$1" = x ]
Siempre es una prueba válida independientemente del valor de $1
, también lo son:
[ "" = "$1" ]
y:
[ -z "${1:+x}" ]
y
case $1 in "") ...; esac
Por supuesto, si desea comprobar que no se proporciona ningún argumento, haría lo siguiente:
[ "$#" -eq 0 ]
Es decir, verifica la cantidad de argumentos pasados al script.
Tenga en cuenta que hoy en día, [ -z "$var" ]
POSIX lo especifica claramente y no puede fallar en [
implementaciones conformes (y bash
lo [
es y lo ha sido durante décadas). Por lo tanto, debería poder confiar en él en bash
scripts o POSIX sh.
Respuesta4
[ x$1 = x ]
es verdadero si $1
no está configurado/nulo/vacío o no.
Pruébalo tú mismo con:
TEST= ;[ x$TEST = x] && echo "TEST is unset"
y
TEST=lolz ;[ x$TEST = x ] && echo "TEST is unset"