Meu shell é zsh. Eu tentei esses comandos no bash, que tiveram sucesso.
ignore_files=(
local
\*.local.\*
.bundle
Gemfile.lock
)
ignore_command=""
for f in "${ignore_files[@]}"; do
ignore_command="$ignore_command -x $f"
done
echo $ignore_command
# print: -x local -x *.local.* -x .bundle -x Gemfile.lock
sudo diff -ruNd $ignore_command <path a> <path-b>
# failed: diff: extra operand '<path-b>'
echo sudo diff -ruNd $ignore_command <path a> <path-b>
# sudo diff -ruNd -x local -x *.local.* -x .bundle -x Gemfile.lock <path a> <path-b>
eval diff -ruNd $ignore_command <path a> <path-b> # success
Parece que a variável não está expandida nesse comando. Eu quero saber por que e como fazê-lo como bash sem eval.
Um comando é uma lista de argumentos, você deseja usar um array para armazenar esses argumentos aqui:
Você provavelmente está confuso com o comportamento de shells do tipo Bourne, onde deixar uma expansão de parâmetro sem aspas é um operador split+glob, então ele transforma uma variável string/escalar em uma lista (ou padrões de correspondência de arquivos) na expansão .
Esse mau comportamento foi corrigido pela
zsh
maioria dos outros shells modernos comorc
,es
,fish
.Você poderia emular esse comportamento dos shells Bourne com
set -o shwordsplit -o globsubst
, mas isso seria retroceder. Especificamente,globsubst
seria um problema no seu caso, pois*.local.*
contém caracteres glob.Em
zsh
, se você deseja dividir uma variável ou executar globbing em sua expansão, você deve perguntar explicitamente:$=var
, divide$var
em$IFS
caracteres.${(s:,:)var}
divide em strings específicas (aqui,
)$~var
: executa globbing (ou correspondência de padrões dependendo do contexto) na expansão (por exemplo, se$var
contém*
,$~var
no contexto da lista será expandido para a lista de arquivos no diretório atual como o Bourne shell$var
)$=~var
: faz divisão e globbing, então é como o$var
do shell Bourne.Neste caso específico, você também pode fazer:
(onde o
^
faz com que a matriz se expanda como emfish
ourc
como--exclude=element1
--exclude=element2
... Na verdade, habilita arcexpandparam
opção para essa expansão como~
habilitaglobsubst
e=
shwordsplit
).