A diferença entre o bash e o zsh que importa aqui está no caminho run2
calls run
, especificamente o efeito de deixar $1
sem aspas.
- Em zsh,
run $1
aplica o operador "remove-if-empty" a$1
, ou seja, chamarun
com o primeiro argumento que foi passado pararun2
, exceto se o primeiro argumento forrun2
estava vazio (ou serun2
foi chamado sem argumento), entãorun
é chamado sem argumento. - Em outros shells no estilo Bourne, como bash,
run $1
aplica o operador “split + glob” a$1
, ou seja, ele divide o primeiro argumento emrun2
em partes separadas por espaços em branco¹, interpreta cada parte como um padrão de caractere curinga² e substitui cada padrão de caractere curinga que corresponde a um ou mais arquivos pela lista de correspondências.
Assim, run2 'a b' c
chama run
com o argumento a b
em zsh (o argumento é passado inalterado), mas chama run
com os dois argumentos a
e b
no bash (dividido em espaços em branco- peças delimitadas).
I want a way to pass a first arg which is a string that has spaces in it, and have that spliced
$@
style into another command. e.g.run2 "a b" c
should produce1: a 2: b 3:
Sua descrição e seu exemplo dizem coisas diferentes. Se você quiser passar o primeiro argumento para o outro comando, use run "$1"
para garantir que o argumento não seja dividido. Passar argumentos inalterados é o ponto inteiro de "$@"
.
Parece que o que você realmente quer fazer é dividir o primeiro argumento para run2
em partes delimitadas por espaço em branco. No bash, você pode fazer isso desativando a expansão de curinga e, em seguida, (assumindo que IFS
não foi alterado do padrão) usando uma expansão sem aspas.
run2 () ( set -f; run $1; )
( echo "$(somecommand)"
é essencialmente equivalente a executar somecommand
em um subshell, e parece que isso é o que você quis dizer em vez de echo $(somecommand)
que aplica split + glob na saída do comando, então eu removi o redundante echo-command-substitution.)
No zsh, você pode usar o caractere =
em uma substituição de parâmetro para realizar a divisão do mundo (e não globbing) no valor.
run2 () { run $=1; }
A sintaxe do zsh não é compatível com a da sh simples. Se você deseja criar um script sh a partir do zsh, você pode usar o emulate
builting:
emulate sh -c '. myscript.sh'
Use emulate ksh
para emular (alguns recursos de) ksh. Isso não emula todos os recursos do bash, mas permite usar matrizes.
¹ Mais geralmente, com base no valor de IFS
.
² A menos que isto tenha sido desativado com set -f
.