Fishシェルの$ argvはbashの$ @とは異なりますか?

Fishシェルの$ argvはbashの$ @とは異なりますか?

いくつかの魚のス​​クリプトを学び、作成しようとしましたが、奇妙な問題に固執しました。

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

実行するとfish ./a.fish -a -b --correct正常に動作し、出力されます。

-a -b --correct --

ただし、$argvに変更し"$argv"て再実行すると、次の結果が表示されます。 質問

その後、bashスクリプトを作成しました。

# a.sh
temp=$(getopt -o abc -l ace,bad,correct -- $@)
echo $temp

で実行してくださいbash ./a.sh -a -b --correct。素晴らしい作品。追加した後もまだ素晴らしい"作品$@です!

だからここに質問があります:

$argvとの違いは何ですか$@

私はこれが単純な交換だと思いましたが、これは私を混乱させます。誰でも私を助けることができますか?どんな助けにも感謝します:)

オペレーティングシステム:Ubuntu 16.04

答え1

はい、殻が違うと違います。straceいつものように、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
$ 

しかし、-scopeでは実際には2つが非常に異なりますstrace

$ 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
$ 

1つ目は引数リストecho(「a」、「b」、「c」)を渡し、2つ目は単一のリストエントリ(「ab c」)を渡します。したがって、あなたのgetopt場合、参照が「$ argv」の場合、引数はgetopt(1)単一要素のリストではなく単一の文字列として渡され、単一の文字列ではgetopt(1)ない項目のリストが期待されるため失敗します。

onはをマークする必要がstraceあります。 1つの仮定は、要素を個々の項目に混在させるのではなく、リストに分割することです。bash"$@"

関連情報