Estoy leyendo un script bash, no entiendo lo que está pasando allí.
#!/bin/sh
[ x$1 = x ]
¿Qué está pasando en la segunda línea y qué [ x$1 = x ]
significa?
Eso comprueba que $1
está vacío, aunque debe citarse (idéntico a [ -z "$1" ]
). Algunos shells muy antiguos no manejaban las cadenas vacías correctamente, 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 así porque la gente todavía lo hace de esa manera.
[ x$1 = x ]
sigue siendo incorrecto, pero[ "x$1" = x ]
sería para shells que tienen un problema donde$1
está!
o(
o-n
...[ "" = "$1" ]
ycase $1 in "")
también estaría bien.[ -z "$1" ]
y[ "$1" = "" ]
todavía no funciona con / bin / sh de Solaris 10, el primero con dash-0.5.4.[ "$1" = "" ]
todavía no funciona con ella/bin/sh
(aunque querría usarla/usr/xpg4/bin/sh
allí, no/bin/sh
). el guión se solucionó al respecto en enero de 2009.Los corchetes indican una prueba , entonces
[ x$1 = x]
sinif
o algo similar no tiene sentido, aunque sintácticamente está bien.Está destinado a evaluar a verdadero si se
x$1
expande ax
, y falso de lo contrario, pero dado que 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:Operadores de prueba del golpe
-z
y-n
también se pueden utilizar, pero son menos portátiles a otros tipos de proyectiles. 1La razón de las comillas, o el
x$1
, es que el lado izquierdo no se expande a nada, lo que sería un error sintáctico:1. En realidad,
test
puede ser una utilidad independiente, pero la mayoría de los shells lo implementan como una función incorporada; compruebe la diferencia entrewhich test
ytype test
. En GNU / Linux seman test
afirma que se refiere a la función integrada, pero si llama (por ejemplo)/usr/bin/test
, esa utilidad parece implementar las características documentadas en la página del manual, incluyendo-z
y-n
.fuente
[ x$1 = x ]
también evaluará a verdadero si$1
es por ejemplo" -o x"
. Tratarsh -xc '[ x$1 = x ] && echo yes' sh ' -o x'
.[ x$1 = x ]
está mal y no tiene sentido.if
usartest
, puede usarlo antes&&
,||
o despuéswhile
o examinar el resultado usando$?
Solo tiene sentido
zsh
. Eso compara la concatenación dex
con el primer argumento del guión ax
. Entonces, el[
comando devuelve verdadero si$1
está vacío o no se proporciona.¿No trabajo porque, en
zsh
cuando una variable de vacío no es citado en contextos de la lista, que se expande a ningún argumento en absoluto en lugar de un argumento vacío, por lo que si$1
fuese definido o vacía, el[
comando sería sólo reciben como argumentos[
,=
la cadena vacía y de lo]
que no podía tener sentido.[ -z "$1" ]
o[ "$1" = "" ]
estaría bien, como en los shells POSIX.En los shells tipo Bourne / POSIX,
[ x$1 = x ]
no tiene sentido. Ese es el operador split + glob que se aplica de alguna manera a la concatenaciónx
y al primer argumento del script con la esperanza de que el resultado=
yyx
, y]
compongan una expresión de prueba válida para el[
comando.Por ejemplo, si el guión se aprobó un
" = x -o x ="
argumento,[
recibiría esos argumentos:[
,x
,=
,x
,-o
,x
,=
,x
,]
, que[
entendería como la comparaciónx
con elx
yx
conx
y devolver cierto.Si
$1
fuera así"* *"
, el shell pasaría al[
comando la lista de archivos en el directorio actual cuyo nombre comienza conx
(la expansión global dex*
), luego la lista de archivos no ocultos (expansión*
) ... que[
es poco probable que pueda para que tenga sentido. Los únicos casos en que eso haría algo sensato es si$1
no contiene comodines o caracteres en blanco.Ahora, lo que a veces encuentras es código como:
Eso se usa para probar si
$1
está vacío o sin configurar.La forma normal de probar una variable vacía o no establecida es:
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 antes o algunas versiones antiguas dedash
(hasta 0.5.4) o lash
de algunos BSD.Eso es porque
[
ve[
,-z
,=
,]
y se queja de que faltan argumentos para el=
operador binario en lugar de entenderlo como el-z
operador unitario aplicado a la=
cadena.Del mismo modo,
[ "$1" = "" ]
falla para algunas implementaciones de[
if$1
is!
or(
.En esas shell /
[
implementaciones:siempre es una prueba válida independientemente del valor de
$1
, también lo son:y:
y
Por supuesto, si desea comprobar que no se proporciona ningún argumento, haría:
Es decir, verifica el número 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 (ybash
's[
es y ha sido por décadas). Por lo tanto, debería poder confiar en él en POSIX sh obash
scripts.fuente
x$1
está concatenando dos cadenasx
y$1
si $ 1 está vacío, x $ 1 es igual a x, y como resultado [x $ 1 = x] será verdadero.x = y
se usa para comparar cadenas en shfuente
x$1
no se cita, por lo que se realiza la división y el bloqueo en esos.[ x$1 = x ]
es verdadero si$1
está desarmado / nulo / vacío o no.Pruébalo con:
TEST= ;[ x$TEST = x] && echo "TEST is unset"
y
TEST=lolz ;[ x$TEST = x ] && echo "TEST is unset"
fuente
[ x$1 = x ]
También es cierto si$1
es por ejemplo" -o x"
. Tratarsh -xc '[ x$1 = x ] && echo yes' sh ' -o x'
.[ x$1 = x ]
está mal y no tiene sentido.