São as únicas opções para expansão do comando bash:
- sem aspas
$(..)
cuja saída é sempre analisada com divisão de strings mudas, ou - citado
"$(..)"
cuja saída é sempre passada junto como uma unidade?
Eu estou tentando replicar no bash uma função de shell de peixe que criei para uso no Mac OS. Minha função de peixe selection
https://superuser.com/a/1165855 pega a seleção na janela frontal e gera os caminhos para uso na substituição de comandos ls -l (selection)
. Eu estava esperando para conseguir a mesma coisa em bash talvez como ls -l $(selection)
.
Eu pensei que era uma questão de citar e assim tentei passar caminhos delimitados por alimentação de linha para o bash printf "%q "
. No entanto, descobri que não importa em qual citação coloquei a saída de substituição de comando, ela estava sendo dividida em espaço em branco.
Exemplo simplificado:
$ touch file\ a file\ b
$ ls $( echo "file\ a file\ b" ) # want expansion equiv to: ls 'file a' 'file b'
ls: a: No such file or directory
ls: b: No such file or directory
ls: file\: No such file or directory
ls: file\: No such file or directory
Não seria o fim do mundo se eu tivesse que usar a substituição de comandos citada como, ls -l "$(selection)"
mas fazendo isso, a saída do comando nunca é dividida, deixa de observar a minha cuidadosa citação. A sintaxe antiga do backtick é diferente?
Engraçado, bash, você tem muitos recursos. Não tem ninguém para permitir cmda $(cmdb-that-generates-parameters-for-cmda)
? Ou um usuário bash simplesmente evita espaços ou símbolos em nomes de arquivos (como um animal) para tornar tudo mais fácil? Obrigado por qualquer resposta.
fonte
;
caracterecmda $(cmdb-that-generates-parameters-for-cmda)
, um exemplo mais literal:transcode $(selection)
. Parece que não é possível, vou começar a usar fish-shell no meu Mac de trabalho.Com
xargs
:Mente as citações. Nota
xargs
não é um Bash builtin (estou mencionando isso em um contexto de seu "Bash, você tem um monte de recursos").Com o
eval
qual é um Bash builtin:Mais uma vez, lembre-se das citações. Isso pode sair pela culatra facilmente . Métodos baseados em mudar a
IFS
( esta outra resposta ) parecem mais seguros. Por outro lado,eval
você pode até fazer isso:Infelizmente, nada disso é tão simples quanto a
ls (selection)
sintaxe do outro shell com a qual você começou. No entanto, você pode simplificar a sintaxe de qualquer solução (?) Com uma função personalizada, por exemplo:Isso permite que você ligue
_ ls selection
, se apenasselection
gerar entrada para axargs
direita. Melhor ainda, isso:torna
_ ls -l "file c" selection
possível. Eu acho que você poderia criar uma função semelhante que usa oIFS
método "alterar o " de outra resposta.Ainda assim, isso não é tão flexível e elegante como o peixe
ls (selection)
. Eu espero que você possa fazerls (selection1) (selection2)
em peixe; a_
função acima não cobre este caso.Por outro lado,
eval ls $(selection1) $(selection2)
pode funcionar seselection1
eselection2
retornar cadeias higienizadas com cotação e / ou escape adequados. Se um invasor puder fazer com que você selecione um arquivo chamado,; rm -rf ~/;
é melhor higienizar bem; ou não usareval
em primeiro lugar.fonte
eval
.