일부 물고기 스크립트를 배우고 작성하려고 하는데 이상한 문제에 봉착했습니다.
# 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
와 사이의 차이점은 무엇입니까 $@
(아니면 Fish와 bash가 변수를 다르게 처리하는지 물어봐야 할까요?)
나는 이것이 단순한 교체라고 생각했지만 이것이 나를 혼란스럽게 합니다. 누구든지 나를 도와줄 수 있나요? 어떤 도움이라도 대단히 감사하겠습니다 :)
운영 체제: 우분투 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에서는 실제로 두 가지가 매우 다릅니다 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
$
첫 번째는 인수 목록 echo
("a", "b", "c")을 전달하고 두 번째는 단일 목록 항목("ab c")을 전달합니다. 따라서 귀하의 getopt
경우 참조가 "$argv"이면 인수는 getopt(1)
단일 요소 목록이 아닌 단일 문자열로 전달되며 getopt(1)
단일 문자열이 아닌 항목 목록을 기대하기 때문에 실패합니다.
on은 를 표시 strace
해야 합니다 . 한 가지 가정은 요소를 개별 항목으로 혼합하는 대신 목록으로 분할한다는 것입니다.bash
"$@"