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.