foo (){
sudo -- sh -c "cd /home/rob; echo \"$@\""
}
.bashrc
sudo를 특정 디렉터리로 변경한 다음 Python 명령을 실행하는 bash 함수를 만들려고 합니다 . 데모 목적으로 위의 예에서는 에코로 변경했습니다.
echo 명령에 모든 인수를 전달한다고 언급했지만 $@
다음 중 하나만 작동합니다.
$ foo 1
1
$ foo 1 2
2": -c: line 0: unexpected EOF while looking for matching `"'
2": -c: line 1: syntax error: unexpected end of file
무엇을 제공합니까? 이 함수에 여러 매개변수를 전달하려면 어떻게 해야 하나요?
답변1
set -v
함수에 추가하면 무슨 일이 일어나는지 확인할 수 있습니다.
$ f (){ set -v; sudo -- sh -c "cd /tmp; echo \"$@\""; }
$ f 1 2
+ sudo -- sh -c 'cd /tmp; echo "1' '2"'
뭐가 문제 야? 사용하면 작은 따옴표 $@
로 요약된 두 개의 문자열이 생성됩니다 . 이 분할을 원하지 않는 경우에 사용할 수 있습니다. Bash 매뉴얼 페이지 섹션을 참조하세요.cd /tmp; echo "1
2"
$*
특수 매개변수:
@... 큰따옴표 내에서 확장이 발생하면 각 인수가 별도의 단어로 확장됩니다. ... If... 단어 내에서 첫 번째 인수의 확장은 원래 단어의 시작 부분과 연결되고, 마지막 인수의 확장은 원래 단어의 마지막 부분과 연결됩니다.
따라서 귀하의 경우 단일 문자열(또는 단어) "xxx$@yyy"는 2개의 문자열 "xxx1"과 "2yyy"로 확장됩니다. set -- 1 2 3
set을 사용하여 이를 테스트 $@
한 다음 printf ">%s<" "$@"
단어 수를 확인할 수 있습니다 "$@"
(printf가 각 인수에 대한 형식을 반복하므로).
$ set -- 1 2 3
$ printf ">%s< " "x$@y"
>x1< >2< >3y<
$ printf ">%s< " "x$*y"
>x1 2 3y<
sh -c command
핵 에 인수를 전달하려면 단일 명령 뒤에 인수로 배치하십시오. 그러나 이는 모든 셸에서 작동하지 않을 수 있습니다.
f (){ set -v; sudo -- sh -c 'cd /tmp; echo "$@"' sh "$@"; }
f 1 2
+ sudo -- sh -c 'cd /tmp; echo "$@"' sh 1 2
추가 sh
매개변수는 첫 번째 매개변수가 셸에서 프로세스 이름으로 사용되기 때문입니다.