Estaba escribiendo algunos guiones y escribí algo como
ARTIFACTS="/SOME/PATH"
[ -d $ARTIFCATS ] && rm -rf $ARTIFACTS/*
Lo que sucedió es que por estupidez ejecuté la segunda línea sin ejecutar la primera. Resultó que [-d ""] devuelve verdadero y la expresión se convirtió en
rm -rf /*
Afortunadamente era solo una máquina de prueba y no era un sudo, pero aunque perdí algunos datos
Mi pregunta es, ¿por qué [-d ""] devuelve verdadero? la documentación indica claramente que verifica si existe una ruta y si es una carpeta
Resolví el problema usando
[ -e $ARTIFACTS ]
que parece funcionar
Salud

rm -rf $ARTIFACTSsin el/*. Esto también eliminaría el$ARTIFACTSdirectorio, lo cual está bien, porque si quiero estar seguro de que existe antes de poner algo en él, lo ejecutaré demkdir -p $ARTIFACTStodos modos. También eliminará los archivos ocultos dentro$ARTIFACTS, lo cual también está bien, porque no escribiríarm -rf $ARTIFACTS/*si$ARTIFACTScontuviera algo que quisiera guardar.Respuestas:
1. Estas dos pruebas devuelven verdadero :
de acuerdo con POSIX (como lo explica @Tim).
2. Pero esto devuelve falso ( no es cierto como se indica en la pregunta)
porque
testse llama con dos argumentos (aunque el segundo es una cadena vacía).3. Es por eso que es una buena práctica usar en
[[ … ]]lugar detest([ … ]), que proporcionan la mayoría (¿todos?) De los shells actuales. Esta construcción verifica si proporciona suficientes argumentos (de lo contrario, arroja un error y aborta)o simplemente se comporta como uno esperaría:
4. Y, como señaló @Gilles, aún más importante es duplicar las sustituciones. Por lo tanto, se
-d "$SOME_UNSET_VAR"expande-d ""y devuelve falso incluso contest(igual al caso 2). Por lo tanto, esto también es compatible con el shell Bournesh:probado con bash 3.00.16 (1) y 4.1.5 (1)
fuente
[[ … ]]pero no son simplessh. La práctica realmente importante es poner comillas dobles sustituciones de comando :[ -d "$ARTIFACTS" ].Esta pregunta ya ha sido respondida en StackOverflow. Dice que de acuerdo con el estándar POSIX,
testsiempre debe devolverse con éxito si se llama con exactamente un argumento no vacío (y sin otros argumentos).Este también debería ser el caso con
test -e(y de hecho está en mi sistema), así que tenga cuidado.En su lugar use:
testluego se llamará con dos argumentos incluso si la variable está vacía y devuelve falso en este caso.fuente
[ ! -z $ARTIFACTS ] && [ -d $ARTIFACTS ]no es mejor: solo atiende el caso particular cuando$ARTIFACTSestá vacío, pero falla cuando$ARTIFACTSpuede contener espacios en blanco o\[?*.[ -d "$ARTIFACTS" ]es la forma correcta de hacerlo (o[[ -d $ARTIFACTS ]]en shells que lo tienen[[ … ]]).Estás equivocado . Funciona porque
$ARTIFACTSahora está configurado en algo.Cuando no se establece una variable, entonces decir
o
sería tanto evaluar a
trueporque implica diciendoy
respectivamente. (Decir
[ foobar ]siempre se evaluaría como verdadero).Diciendo
resulta útil en tales situaciones.
help sette diría:fuente
Vea que configuró la variable ARTIFACTS y que estaba buscando ARTIFCATS. ¿Probablemente escribiendo mal?
De todos modos, -d así como -e producirían los mismos resultados en variables no establecidas.
Por lo tanto, use comillas dobles y le ayudará.
NOTA: Si su "/ SOME / PATH" tiene alguna carpeta con espacio, el script que mencionó se romperá con el error "operador binario esperado".
Ejemplo:
Lo haré bien. No olvide poner también comillas en la
rminvocación (rm -rf $ARTIFACTSeliminaría alegremente y/homeluego se quejaría porbackup/*no existir).Además, incluir la
-Lverificación se asegurará de que sea un directorio y no solo un enlace simbólico a un directorio.Así que básicamente,
fuente