빈 쉘 변수를 사용할 때 오류 발생


22

때로는 $PROJECT_HOME/*프로젝트의 모든 파일을 삭제하기 위해 사용합니다. 환경 변수 PROJECT_HOME가 설정되어 있지 않으면 (내가 su하고 새 사용자 에게이 환경 변수가 설정되어 있지 않기 때문에) 루트 폴더에서 모든 파일을 삭제하기 시작합니다. 이것은 종말입니다.

bash쉘에서 정의되지 않은 환경 변수를 사용할 때 오류가 발생 하도록 구성 하려면 어떻게 해야합니까?


5
set -u당신이 원하는 것을 할 것입니다.
cuonglm

답으로 만들 수 있습니까?

2
물론 vars를 빈 문자열로 초기화하지는 않습니다. [ -z "$VAR" ]초기화되지 않은 상태 VAR에서도 작동합니다 . 초기화는 바람직하지 않은 동작을 보여주기위한 것일뿐입니다. 내 요점은 vars가 빈 문자열로 초기화되고 어떤 식 으로든 rm -r "$PROJECT_HOME"/*실수로 실행 set -u하면 "apocalyptic"동작을 얻게됩니다. IHMO, 컴퓨터의 전체 내용을 보호하는 데있어 미안보다 안전합니다. set -u안전하지 않습니다.
PSkocik 2016 년

3
"매우 길다"? 위험한 작업을 수동으로 수행 하는 편리한 방법을 찾지 않아야 합니다. 대신, 원하는 것을 수행하는 함수, 별명 또는 스크립트를 작성해야합니다. 이 경우 @PSkocik의 제안 된 명령에서 별칭을 만드는 것이 안전 하고 편리합니다.
Kyle Strand

1
사용자가 설정하면 어떻게 PROJECT_HOME=/etc됩니까? 빈 값을 확인하는 것만으로는 대격변을 예방할 수 없습니다. 루트로 실행할 때 신뢰할 수없는 사용자의 변수를 사용해서는 안됩니다.
Barmar

답변:


27

POSIX 쉘에서는 set -u를 사용할 수 있습니다 :

#!/bin/sh

set -u
: "${UNSET_VAR}"

또는 매개 변수 확장 사용 :

: "${UNSET_VAR?Unset variable}"

귀하의 경우 설정 대신 빈 변수에 실패 하는 :?대신 대신 사용해야 ?합니다.

rm -rf -- "${PROJECT_HOME:?PROJECT_HOME empty or unset}"/*

17
[ -z "$PROJECT_HOME" ] || rm -r "$PROJECT_HOME"/*

또한이 경우 잡을 것 PROJECT_HOME 입니다 설정하지만, 아무것도 포함하지 않습니다.

예:

1) 이렇게하면 시스템에서 삭제할 수있는 거의 모든 내용이 삭제됩니다 (내부 점 파일 제외 /).

set -u
PROJECT_HOME=
rm -r "$PROJECT_HOME"/*

2) 이것은 아무것도하지 않습니다 :

PROJECT_HOME=
[ -z "$PROJECT_HOME" ] || rm -r "$PROJECT_HOME"/* 

프로젝트를 완전히 제거하고 다시 만드는 것은 다른 옵션 일 수 있습니다 (도트 파일을 제거하려는 경우).

#no apocalyptic threats in this scenario
rm -r "$PROJECT_HOME"
mkdir "$_" 

1
-z괜찮지 만 $PROJECT_HOME디렉토리이기 -d때문에 더 좋을 것입니다. [[ -d $PROJECT_HOME ]] && rm -r "$PROJECT_HOME".
kojiro 2016 년

2
PROJECT_HOME이 비 디렉토리로 설정되면 오타로 인한 치명적이지 않은 오류입니다. -d검사는 그 오류를 숨길 것입니다. 나는 그것이으로 진행하면 더 나은 생각 rm하고 rm큰 소리에 대해 알아 뿌려줍니다.
PSkocik

2
PROJECT_HOME이 설정되었지만 이름이 디렉토리가 아닌 경우 [[ -d $PROJECT_HOME ]] && rm -r "$PROJECT_HOME"아무 것도 자동으로 수행하지 않습니다. 그러나 [[ -z $PROJECT_HOME ]] || rm -r "$PROJECT_HOME"디렉토리가 아닌 파일 인 경우에도 "$ PROJECT_HOME"을 자동으로 삭제합니다. 오류 메시지를 얻는 것은 결코 문제가되지 않습니다 :if [[ -d $PROJECT_HOME ]]; then rm -r "$PROJECT_HOME"; else printf '%s is not a directory\n' "$PROJECT_HOME" >&2; fi
kojiro

1
"우연히"설정 PROJECT_HOME="/."...
Hagen von Eitzen 2016 년

1
@HagenvonEitzen PROJECT_HOME이 루트로 설정된 경우 PROJECT_HOME을 비우는 절차는 루트를 비 웁니다. 그것은 기대되고 완벽하게 합리적인 행동입니다. 그리고 당신은 그 마지막 점이 필요하지 않습니다.
PSkocik 2016 년

0

이를 수행하는 다른 방법 :

rm -r "${somevar:-/tmp/or_this_if_somevar_is_empty}"/*

많은 변수 대체가 있습니다. 위의 것은 "somevar"가 비어있을 때입니다 (이 경우에는 삭제를 시도합니다 /tmp/or_this_if_somevar_is_empty/*)


1
또는 : rm -fr ${ENV_VAR:?suitably caustic message here}/*하지만 여전히 값이 간단한 테스트를 파괴하는 방법에는 여러 가지가 있다는 것을 지적, 루트 디렉토리에 매핑되지 않는 가치가 검사 할 수 있습니다 //, /.., /usr/who/../.., ...
조나단 레플러

예. 당신은 매개 변수 확장을 사용하려고하는 경우, 당신은뿐만 아니라 사용할 수 있습니다 실제로 오류가 발생하는 일
디지털 외상
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.