알겠습니다. 이 코드가 있어요
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
바라보다: