CD용 래퍼를 작성할 때 cd "$1" 대신 cd "$@"를 사용해야 하는 이유는 무엇입니까?

CD용 래퍼를 작성할 때 cd "$1" 대신 cd "$@"를 사용해야 하는 이유는 무엇입니까?

다른 곳에서는 다음과 같은 CD 함수를 본 적이 있습니다.

cd()
{
 builtin cd "$@"
}

$@대신 사용하는 것이 권장되는 이유는 무엇입니까 $1?

테스트 디렉터리 "r st"를 만들고 이 함수가 포함된 스크립트를 호출했는데 어떤 방식으로든 작동했습니다.

$ . cdtest.sh "r st"

하지만 $ . cdtest.sh r st사용 여부에 관계없이 "$@"실패합니다."$1"

답변1

에 따르면 매개변수를 허용하기 때문입니다 bash(1).cd

   cd [-L|[-P [-e]] [-@]] [dir]
          Change  the  current  directory to dir.  if dir is not supplied,
          ...

따라서 디렉토리는 $1옵션(예: -L다른 플래그)일 수 있으므로 실제로 존재하지 않을 수도 있습니다.

얼마나 나쁜가요?

$ cd -L /var/tmp
$ pwd
/var/tmp
$ cd() { builtin cd "$1"; }
$ cd -L /var/tmp
$ pwd
/home/jhqdoe
$ 

예상대로 사용하지 않으면 상황이 크게 잘못될 수 있습니다 cd "$1".

답변2

을 사용하면 "$@"모든 매개변수가 cdas 에 전달되고 $1첫 번째 매개변수만 전달됩니다.

귀하의 예에서

$ . cdtest.sh "r st"

하나의 매개변수만 전달하기 때문에 항상 작동하지만, 플래그도 전달하는 경우(예:

$ . cdtest.sh -L "r st"

그러면 디렉토리가 완전히 누락된 상태로 확장된 "$@"경우에만 올바르게 수행됩니다 ."$1"cd -L

하지만

$ . cdtest.sh r st

두 가지 인수를 cd에 전달하기 때문에 두 경우 모두 실패합니다. r이는 stcd를 수행하는 유효한 방법이 아닙니다. 매개변수는 공백으로 구분되며 r\ st하나의 매개변수로 간주하려면 따옴표로 묶거나(첫 번째 예에서와 같이) 이스케이프( )해야 합니다.

그러나 cd 의 경우 플래그를 전달하는 경우가 매우 드물고 여러 디렉터리를 전달할 수 없으므로 또는 를 사용할 때의 실제 "$1"차이점을 볼 수 없습니다 "$@". 하지만 다른 명령의 경우~ 할 것이다"$@"차이점을 인지하고 있으므로 이와 같은 래퍼 함수나 스크립트를 만들고 싶을 때 항상 사용하는 것이 가장 좋습니다.

답변3

이런 경우도 있는데,아니요매개변수:

$ cd /tmp; cd; pwd
/home/muru
$ cd_func() { builtin cd "$1"; }
$ cd_func /tmp; cd_func; pwd
/tmp

cd매개변수 없이 홈 디렉토리를 변경합니다. 인수가 없으면 "$@"아무 것도 확장되지 않지만 "$1"빈 문자열로 확장됩니다. 이들은 다릅니다:

$ args() { for i in "$@"; do echo "|$i|"; done; }
$ args
$ args ""
||

답변4

Bash 스크립트에 대한 매개변수는 공백으로 구분됩니다. $1이 첫 번째 매개변수입니다. 귀하의 예에서 ...

예제 1에서 $1은 문자열 "r st"입니다... 두 번째 예에서 $1은 단일 문자열 "r"입니다...

$@는 모두 매개변수입니다.

관련 정보