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 $1aplica o operador "remove-if-empty" a$1, ou seja, chamaruncom o primeiro argumento que foi passado pararun2, exceto se o primeiro argumento forrun2estava vazio (ou serun2foi chamado sem argumento), entãoruné chamado sem argumento. - Em outros shells no estilo Bourne, como bash,
run $1aplica o operador “split + glob” a$1, ou seja, ele divide o primeiro argumento emrun2em 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" cshould 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 .