인수로 사용될 때 eval " 명령 \"$@\" ", "$@" 및 "$(echo $@)"의 다른 동작

인수로 사용될 때 eval " 명령 \"$@\" ", "$@" 및 "$(echo $@)"의 다른 동작

임의로 이름이 지정된 function 을 통해 Tor 브라우저(firefox)에 프로그래밍 방식으로 여러 매개변수를 전달하고 싶습니다 tor. 이것은 명령을 위한 것입니다 tor search terms. 짜잔! 내 검색어입니다. 이 세 가지 변형을 사용할 때,

~/tor-browser_en-US/Browser/start-tor-browser -search "$(echo $@)"

eval "~/tor-browser_en-US/Browser/start-tor-browser -search \"$@\""

~/tor-browser_en-US/Browser/start-tor-browser -search "$@"

처음 두 줄만 동일한 기능을 수행하는 것 같습니다. 단일 Tor 브라우저 창이 임의의 텍스트 콘텐츠에서 용어를 검색하게 합니다. 그러나 세 번째 줄은 각 단어에 대해 새로운 검색 창을 생성합니다.

왜 이런 문제가 발생합니까?

명확히하겠습니다. 나는 해결책을 찾는 것이 아니라 bahviour에 대한 설명에 관심이 있습니다.

답변1

세 번째 버전의 "$*"경우 "$@".

설명하다

이를 설명하기 위해 몇 가지 위치 매개변수를 설정해 보겠습니다.

$ set -- arg1 arg2 arg3

이제 공식을 사용하여 echo읽어 보겠습니다.

$ printf "%s\n" "$(echo $@)"
arg1 arg2 arg3

"$@"그들이 무엇을 하는지 봅시다 :

$ printf "%s\n" "$@"
arg1
arg2
arg3

차이점은 단일 문자열 "$@"이 아닌 세 단어로 확장된다는 것입니다. "$(echo $@)"비슷한 동작을 원하면 다음을 "$(echo $@)"사용해야 합니다 "$*".

$ printf "%s\n" "$*"
arg1 arg2 arg3

문서

에서 man bash:

"$*"단일 문자열을 생성합니다.

"$*"는 "$1c$2c..."와 동일합니다. 여기서 c는 IFS 변수 값의 첫 번째 문자입니다.

대조적으로, 일련의 단어를 생성하는 상태는 다음과 같습니다 man bash.$@

"$@"은 "$1" "$2"와 동일합니다...

사용평가

관찰하다:

$ echo 'printf "%s\n" "' "$@" '"'
printf "%s\n" " arg1 arg2 arg3 "

echobash가 명령을 평가할 때 "$@"별도의 단어로 확장됩니다. echo그러나 이러한 개별 단어는 문자열로 결합됩니다. 우리가 그것을 볼 때 전에 우리는 이것을 보았습니다 "$(echo $@)". eval작동 원리는 비슷합니다. 모든 인수로부터 문자열을 생성하고 문자열을 계산합니다. 그러므로:

$ eval 'printf "%s\n" "' "$@" '"'
 arg1 arg2 arg3 

이는 또한 문서화되어 있습니다 man bash.

평가[매개변수...]
args를 읽고 함께 연결하여 명령을 형성합니다. 그런 다음 명령은 쉘에서 읽고 실행됩니다.

답변2

차이점을 확인하려면 더 간단한 예를 살펴보세요.

$ set "a b" c "d e"
$ printf "%s\n" "$@"
a b
c
d e

아까 말씀하신 게 바로 그거예요.~해야 한다사용은 간단하고 이해하기 쉽고 수정하기 쉽습니다.

$ printf "%s\n" "$(echo $@)"
a b c d e

$@먼저 여기를 확장하세요.인용되지 않음(명령어 대체 주변의 따옴표는 별도이며 아직 적용되지 않았습니다.) 와 동일하며 $(echo a b c d e), printf형식 문자열 뒤에 추가 매개변수가 있습니다.

$ eval "printf \"%s\n\" \"$@\""
a b c d e

여기에는 $@가 인용되어 있지만 확장은 위의 2번과 동일한 출력을 생성하는 명령으로 연결되는 eval( printf "%s\n" a b, c및 )에 대한 3개의 별도 인수를 생성합니다.d e

관련 정보