O $ argv no fish shell é diferente de $ @ no bash?

2

Eu estava tentando aprender e escrever alguns scripts de peixe, mas encontrei um problema estranho.

# a.fish
# this is a fish script 
set temp (getopt -o abc -l ace,bad,correct -- $argv)
echo $temp

Quando eu corri o fish ./a.fish -a -b --correct funcionou bem e a saída

-a -b --correct --

No entanto, quando alterei o $argv para "$argv" e o executei novamente, recebi esse

Entãoeuescreviumscriptbash

#a.shtemp=$(getopt-oabc-lace,bad,correct--$@)echo$temp

eexecutoucombash./a.sh-a-b--correct.Funcionoubem.Depoisdeadicionar" em torno de $@ , ainda funcionou bem!

Então, vem a pergunta:

Qual é a diferença entre $argv e $@ (ou talvez eu deva perguntar se fish e bash lidam com variáveis de maneira diferente?)

Eu pensei que era apenas uma substituição simples, mas isso me confundiu. Alguém pode me ajudar? Qualquer ajuda será apreciada:)

OS: ubuntu 16.04

    
por Charles 12.10.2017 / 18:46

1 resposta

2

Sim, diferentes camadas são diferentes. strace , como sempre, pode ajudar a mostrar exatamente o que é enviado por meio de uma chamada execve(2) .

$ cat fecho
/usr/bin/echo $argv
$ cat fechoquoted 
/usr/bin/echo "$argv"
$ fish ./fecho a b c
a b c
$ fish ./fechoquoted a b c
a b c
$ 

No entanto, estes dois são realmente diferentes sob o strace -scope:

$ strace -qq -f -e trace=execve fish ./fecho a b c
execve("/usr/bin/fish", ["fish", "./fecho", "a", "b", "c"], [/* 22 vars */]) = 0
[pid 15532] execve("/usr/bin/echo", ["/usr/bin/echo", "a", "b", "c"], [/* 21 vars */]) = 0
a b c
$ strace -qq -f -e trace=execve fish ./fechoquoted a b c
execve("/usr/bin/fish", ["fish", "./fechoquoted", "a", "b", "c"], [/* 22 vars */]) = 0
[pid 15542] execve("/usr/bin/echo", ["/usr/bin/echo", "a b c"], [/* 21 vars */]) = 0
a b c
$ 

O primeiro passa uma lista de argumentos para echo ("a", "b", "c") e o segundo um único item de lista ("a b c"). Portanto, no seu caso getopt , quando citado como "$ argv", os argumentos são passados para getopt(1) como uma única string, não como uma lista de elementos individuais, e getopt(1) falha como deseja uma lista de itens, não uma única string.

Um strace on bash deve mostrar o que "$@" faz; Uma hipótese seria dividir os elementos em uma lista, em vez de separá-los como um único item.

    
por 12.10.2017 / 19:38