Digamos que eu tenha um script fazendo:
some-command "$var1" "$var2" ...
E, no caso de var1
estar vazio, prefiro que seja substituído por nada em vez 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 se expandir para nada no bash, zsh ou semelhante? Eu ainda posso querer usar globbing no restante dos argumentos, então desabilitar isso e não citar a variável não é uma opção.
bash
shell-script
zsh
variable
muru
fonte
fonte
man
página? (-;Respostas:
Os reservatórios compatíveis com Posix e Bash têm
${parameter:+word}
:Então você pode fazer:
e foram
var1
verificados e"$var1"
usados se estiverem definidos e não vazios (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 no zsh. Você precisa repetir a variável, para que não seja o ideal, mas funciona exatamente como você queria.
Se você deseja que uma variável definida como vazia seja expandida para um argumento vazio, use em
${var1+"$var1"}
vez disso.fonte
word
parte.:+
e+
.sh
/dash
para scripts em potencial de ponto de estrangulamento, então sempre aprecio quando alguém mostra como uma coisa é possível sem recorrer ao Bash.É o que
zsh
faz por padrão quando você omite as aspas:Na verdade, a única razão pela qual você ainda precisa de aspas no zsh em torno da expansão de parâmetros é evitar esse comportamento (a remoção vazia), pois
zsh
não tem outros problemas que afetam outras shells quando você não cita expansões de parâmetros (a divisão implícita + glob) .Você pode fazer o mesmo com outros shells do tipo POSIX se desativar o split e glob:
Agora, eu argumentaria que, se sua variável puder ter um valor 0 ou 1, deve ser uma matriz e não uma variável escalar e use:
E use
var1=(value)
quandovar1
deve conter um valor,var1=('')
quando deve conter um valor vazio evar1=()
quando não deve conter nenhum valor.fonte
Eu me deparei com isso usando o rsync em um script bash que iniciava o comando com ou sem uma
-n
alternância de execuções a seco. Acontece que o rsync e vários comandos gnu tomam''
como primeiro argumento válido e agem de maneira diferente do que se não estivesse lá.Isso levou algum tempo para depurar, pois os parâmetros nulos são quase completamente invisíveis.
Alguém na lista rsync me mostrou uma maneira de evitar esse problema, além de simplificar bastante minha codificação. Se bem entendi, essa é uma variação da última sugestão de @ Stéphane Chazelas.
Crie seus argumentos de comando em várias variáveis separadas. Eles podem ser configurados 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-a 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 que está vazia simplesmente desaparece usando esse método.
Eu sei que usar eval é altamente desaprovado. Não me lembro de todos os detalhes, mas parecia que precisava para que as coisas funcionassem dessa maneira - algo relacionado ao manuseio de parâmetros com espaço em branco incorporado.
Exemplo:
fonte