Digamos que eu tenha um script fazendo:
some-command "$var1" "$var2" ...
E, caso var1
esteja vazio, prefiro que seja substituído por nada ao invés da string vazia, para que o comando executado seja:
some-command "$var2" ...
e não:
some-command '' "$var2" ...
Existe uma maneira mais simples do que testar a variável e incluí-la 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
Existe uma substituição de parâmetro que pode expandir para nada em bash, zsh ou algo semelhante? Talvez eu ainda queira usar o globbing no restante dos argumentos, portanto, desativá-lo e remover as aspas da variável não é uma opção.
Shells compatíveis com Posix e Bash têm
${parameter:+word}
:Então você pode apenas fazer:
e deve
var1
ser verificado e"$var1"
usado se estiver definido e não vazio (com as regras comuns de aspas duplas). Caso contrário, ele se expande para nada. Observe que apenas a parte interna é citada aqui, não a coisa toda.O mesmo também funciona em zsh. Você tem que repetir a variável, então não é o ideal, mas funciona exatamente como você queria.
Se você deseja que uma variável definida, mas vazia, se expanda para um argumento vazio, use -a
${var1+"$var1"}
.Isso é o que
zsh
acontece por padrão quando você omite as aspas:Na verdade, a única razão pela qual você ainda precisa de aspas em zsh em torno da expansão de parâmetros é para evitar esse comportamento (a remoção vazia), pois
zsh
não há outros problemas que afetam outros shells quando você não cita as expansões de parâmetros (a divisão implícita + globo) .Você pode fazer o mesmo com outros shells do tipo POSIX se desabilitar split e glob:
Agora, eu diria que se sua variável pode ter valor 0 ou 1, ela deve ser uma matriz e não uma variável escalar e usar:
E use
var1=(value)
quandovar1
deve conter um valor,var1=('')
quando deve conter um valor vazio evar1=()
quando não deve conter nenhum valor.Encontrei isso usando rsync em um script bash que iniciava o comando com ou sem um
-n
para alternar execuções secas. Acontece que o rsync e vários comandos gnu assumem''
como um primeiro argumento válido e agem de maneira diferente do que se não estivessem lá.Isso demorou um pouco para depurar, pois os parâmetros nulos são quase completamente invisíveis.
Alguém na lista de rsync me mostrou uma maneira de evitar esse problema, além de simplificar bastante minha codificação. Se bem entendi, esta é uma variação da última sugestão de @Stéphane Chazelas.
Construa seus argumentos de comando em várias variáveis separadas. Eles podem ser definidos em qualquer ordem ou lógica adequada ao problema.
Então, no final, use as variáveis para construir uma matriz com tudo em seu devido lugar e use isso como argumentos para o comando real.
Dessa forma, o comando é emitido apenas em um local do código, em vez de ser repetido para cada variação dos argumentos.
Qualquer variável vazia simplesmente desaparece usando este método.
Eu sei que usar eval é altamente desaprovado. Não me lembro de todos os detalhes, mas parecia precisar dele para fazer as coisas funcionarem dessa maneira - algo relacionado ao manuseio de parâmetros com espaço em branco incorporado.
Exemplo: