Digamos que tengo un script haciendo:
some-command "$var1" "$var2" ...
Y, en el caso de que var1
esté vacío, prefiero que se reemplace con nada en lugar de la cadena vacía, para que el comando ejecutado sea:
some-command "$var2" ...
y no:
some-command '' "$var2" ...
¿Hay una manera más simple que probar la variable e incluirla condicionalmente?
if [ -n "$1" ]; then
some-command "$var1" "$var2" ...
# or some variant using arrays to build the command
# args+=("$var1")
else
some-command "$var2" ...
fi
¿Hay una sustitución de parámetros que puede expandirse a nada en bash, zsh o similares? Es posible que todavía quiera usar globbing en el resto de los argumentos, por lo que deshabilitar eso y desarmar la variable no es una opción.
bash
shell-script
zsh
variable
muru
fuente
fuente
man
página? (-;Respuestas:
Los shells y Bash compatibles con Posix tienen
${parameter:+word}
:Entonces solo puedes hacer:
y han
var1
sido verificados y"$var1"
utilizados si está configurado y no está vacío (con las reglas normales de comillas dobles). De lo contrario, se expande a la nada. Tenga en cuenta que aquí solo se cita la parte interna , no todo.Lo mismo también funciona en zsh. Debe repetir la variable, por lo que no es ideal, pero funciona exactamente como lo deseaba.
Si desea que una variable set-but-empty se expanda a un argumento vacío, use
${var1+"$var1"}
en su lugar.fuente
word
parte.:+
y+
.sh
/dash
para posibles guiones de punto de estrangulamiento, por lo que siempre aprecio que alguien muestre cómo es posible una cosa sin recurrir a Bash.Eso es lo que
zsh
hace por defecto cuando omite las comillas:En realidad, la única razón por la que todavía necesita comillas en zsh alrededor de la expansión de parámetros es para evitar ese comportamiento (la eliminación vacía) ya
zsh
que no tiene los otros problemas que afectan a otros shells cuando no cita las expansiones de parámetros (la división implícita + glob) .Puede hacer lo mismo con otros shells similares a POSIX si deshabilita split y glob:
Ahora, argumentaría que si su variable puede tener un valor 0 o 1, debería ser una matriz y no una variable escalar y usar:
Y use
var1=(value)
cuándovar1
debe contener un valor,var1=('')
cuándo debe contener un valor vacío yvar1=()
cuándo no debe contener ningún valor.fuente
Me encontré con esto usando rsync en un script bash que inició el comando con o sin
-n
alternar para ejecutar en seco. Resulta que rsync y varios comandos gnu toman''
como un primer argumento válido y actúan de manera diferente que si no estuvieran allí.Esto llevó bastante tiempo a la depuración ya que los parámetros nulos son casi completamente invisibles.
Alguien en la lista de rsync me mostró una forma de evitar este problema al tiempo que simplificaba enormemente mi codificación. Si lo entiendo correctamente, esta es una variación de la última sugerencia de @ Stéphane Chazelas.
Construya sus argumentos de comando en varias variables separadas. Estos se pueden configurar en cualquier orden o lógica que se adapte al problema.
Luego, al final, use las variables para construir una matriz con todo en su lugar apropiado y use eso como argumentos para el comando real.
De esta forma, el comando solo se emite en un lugar del código en lugar de repetirse para cada variación de los argumentos.
Cualquier variable que esté vacía simplemente desaparece con este método.
Sé que usar eval está muy mal visto. No recuerdo todos los detalles, pero parecía necesitarlo para que las cosas funcionen de esta manera, algo que ver con el manejo de parámetros con espacios en blanco incrustados.
Ejemplo:
fuente