변수가 비어 있거나 설정되지 않은 경우 [ -d $dirname ]이 일치하는 이유는 무엇입니까? 이로 인해 홈 디렉토리의 내용이 삭제되는 이유는 무엇입니까?

변수가 비어 있거나 설정되지 않은 경우 [ -d $dirname ]이 일치하는 이유는 무엇입니까? 이로 인해 홈 디렉토리의 내용이 삭제되는 이유는 무엇입니까?

알겠습니다. 이 코드가 있어요

dirname=

if [ -d $dirname ];
 then
 cd $dirname && rm *
fi

보시다시피 이 빈 변수가 있는데 이와 같이 단일 대괄호가 포함된 빈 변수를 사용할 때 모든 사용자의 홈 디렉터리 파일이 삭제되는 이유를 알고 싶습니다.

대괄호를 사용하면 사용자의 홈 디렉토리 파일이 삭제되지 않습니다.

이와 같이

dirname=

if [[ -d $dirname ]];
 then
 cd $dirname && rm *
fi

단일 대괄호와 이중 대괄호를 사용할 때 구문의 차이점에 대해 읽었습니다.

왜 이런 일이 발생하는지 알 수 있나요?

답변1

인수가 전달되지 않으면 cd기본 디렉터리(대부분의 경우 사용자의 홈 디렉터리 $HOME)로 변경됩니다.

-d이 질문의 흥미로운 부분은 bash test[내장 연산자 에 아무것도 전달하지 않을 때 bash가 0으로 종료되는 것처럼 보인다는 것입니다 (제 생각에는 예상치 못한 일입니다).

변수를 공백으로 설정하면 dirname실제로 다음 명령이 실행됩니다.

if [ -d ]; then
    cd && rm *
fi

나에게는 해당 블록 내의 코드가 if실행된다는 것이 놀랍지만 내 컴퓨터에서는 실제로 실행되고 있음을 확인할 수 있습니다. 위의 설명에서 설명했듯이 test이는 더 이상 -d연산자로 해석되지 않고 비어 있지 않은 문자열이므로 단순히 0을 반환합니다. 이 동작을 방지하는 한 가지 방법은 변수를 따옴표로 묶는 것입니다.

if [ -d "$dirname" ]; then
    cd "$dirname" && rm *
fi

이 경우 비어 있으면 0이 아닌 종료 코드를 올바르게 계산하는 연산자를 $dirname전달하므로 블록 내부의 코드는 실행되지 않습니다.""-d

답변2

인용되지 않은 콘텐츠는 $dirname토큰화의 영향을 받습니다. 비어 있으면 분할됩니다.삭제됨[ -d $dirname ], 합계에는 합계 cd $dirname만 남습니다 .[ -d ]cd

첫 번째에서는 [매개변수가 하나만 표시됩니다( [및 사이 ]). 이 경우 테스트는 매개변수가 비어 있지 않은 문자열인지 확인하는 것입니다. -d예, 테스트는 사실입니다. (이것은 null을 [ -z $var ]테스트하는 방법 과 비슷 $var하지만 [ -n $var ]전혀 작동하지 않습니다.)

의 경우 cd일반 파일이 cd사용자의 홈 디렉터리로 변경되므로 여기서 rm *그런 일이 발생합니다.


를 사용하면 일반 명령어와는 달리 특별한 쉘 구조이므로 [[ .. ]]단어 분리가 발생하지 않습니다 .[[[

해결책은큰따옴표로 변수 확장, 다양한 이유로 인해 대부분의 상황에서 이 작업을 수행하고 싶을 것입니다. 이와 같이:

if [ -d "$dirname" ]; then
    cd -- "$dirname" && rm ./*
fi

바라보다:

관련 정보