いくつかの魚のスクリプトを学び、作成しようとしましたが、奇妙な問題に固執しました。
# 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
"$@"