디렉토리 이름에 공백이 있으면 bash 변수를 사용하여 디렉토리로 이동하는 것이 작동하지 않습니다.


11

변수에 다음 명령을 저장하고 싶다고합시다.

cd "/cygdrive/c/Program Files/"

그래서 나는 이것을한다

dir="cd \"/cygdrive/c/Program Files/\""

프로그램 파일 디렉토리로 이동하는 명령을 저장해야하므로 $ dir을 입력하면 해당 디렉토리로 이동합니다. 인용문이 제대로 이스케이프되었는지 확인하려면 다음을 입력합니다.

echo $dir

나에게주는

cd "/cygdrive/c/Program Files/"

그래서 모든 것이 잘 작동해야합니다. 그러나 입력하면

$dir

나는 얻다

bash: cd: "/cygdrive/c/Program: No such file or directory

내가 뭘 잘못하고 있죠? Cygwin을 사용하고 있지만이 문제는 일반적으로 bash에 적용된다고 가정합니다.


디렉토리 이름 주위의 따옴표를 제거하고 대신 백 슬래시로 공백을 이스케이프 처리하십시오.
Mike Fitzpatrick

답변:


8

짧은 대답 : BashFAQ # 050 참조 ( "명령을 변수에 넣으려고하지만 복잡한 경우는 항상 실패합니다!").

긴 대답 : bash는 명령을 구문 분석 할 때 변수를 바꾸기 전에 따옴표를 구문 분석합니다. 변수 값으로 따옴표를 다시 구문 분석하지 않으므로 유용한 것을 수행하지 않습니다. 명령 구문 분석 한 후 명령 표시하므로 echo를 사용하여 명령을 확인하는 것은 완전히 잘못된 것입니다 . 실제로 실행되고있는 것을 보려면 set -x셸 인쇄 명령을 실행하거나 printf "%q " $dir; echo일반 에코 대신 사용하십시오 .

복잡한 명령 (예 : "단어"에 공백이나 다른 특수 문자가 포함 된 명령)을 저장하려면 간단한 텍스트 변수 대신 배열에 넣은 다음` "$ { array [@]} "와 같이 :

dir=(cd "/cygdrive/c/Program Files/")
"${dir[@]}"

이제, 타입을 쉽게 입력 할 수있는 것이 목표라면 분명히 갈 길이 아닙니다. 대신 쉘 별명 또는 함수를 사용하십시오.

alias dir='cd "/cygdrive/c/Program Files/"'
dir

또는

dir() { cd "/cygdrive/c/Program Files/"; }
dir

7

bash가 확장되면 $dir단어 분리 및 globbing 만 수행합니다. 단어 분할은 cd, "/cygdrive/c/Program및 세 단어를 생성합니다 Files/". 그런 다음 실행할 명령 cd에는 두 개의 인수가 있습니다. 기존 디렉토리가 아닌 cd첫 번째 인수 만 살펴 봅니다 "/cygdrive/c/Program.

변수의 내용에 대해 전체 셸 평가를 수행하려면 eval다음을 사용하십시오 .

eval "$dir"

주위에 큰 따옴표가 필요합니다 $dir. 그렇지 않으면 단어 분리가 먼저 수행되고 eval인수와 공백이 연결됩니다. 이것은 여기에서 작동하지만 일반적으로 좋지 않습니다 (예 : 파일 이름에 두 개의 연속 공백이있는 경우).

그러나 문자열은 실행하려는 쉘 명령을 저장하는 올바른 방법이 아닙니다. 특별한 요구 사항이 없으면 대신 함수를 사용해야합니다.

dir () {
  cd "/cygdrive/c/Program Files/"
}

당신이 정말로 입력에 관심이 있다면 $dir특정 디렉토리로 전환하려면이 bash는 4 있기 때문에, 단순한 예가 아니다 넣어 shopt -s autocd당신의 .bashrc및 설정

dir="/cygdrive/c/Program Files/"

그 후에는 단지 "/cygdrive/c/Program Files/"또는 "$dir"쉘 프롬프트에서 입력하여 해당 디렉토리로 전환 할 수 있습니다. 여전히 큰 따옴표가 필요합니다 $dir. 마음에 들지 않으면 bash 대신 zsh를 사용하십시오.


6

변수에 명령을 저장하는 것은 일반적으로 좋은 생각이 아닙니다. 그것이 기능과 별칭의 목적입니다.

오히려

dir="cd \"/cygdrive/c/Program Files/\""

다음 중 하나를 시도하십시오.

dir="/cygdrive/c/Program Files"
...
cd "$dir"

또는

dir() { cd "/cygdrive/c/Program Files"; }
dir

또는

alias dir='cd "/tmp/Program Files"'
...
dir

변수에 디렉토리 이름을 저장하는 첫 번째 형식은 조금 더 타이핑한다는 것을 의미하지만을 수행하는 명령을 실행할 때 더 명확합니다 cd. 두 번째는 달성하려는 것에 가장 가깝습니다. (나는 bash에서 별명을 많이 사용하지 않습니다. 실제로 함수보다 어떤 이점이 있는지 확실하지 않습니다.)

편집하다 :

그리고 dir아마도 그 이름으로 된 기존 명령이 있기 때문에 별칭 또는 함수의 이름이 잘못되었을 ls수 있습니다 (적어도 GNU coreutils가있는 경우 기본적으로 버전입니다 ).


upvoteStoring commands in variables is generally not a good idea. That's what functions and aliases are for.
Rob

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.