[validation] Bash 스크립트에 대한 매개 변수 유효성 검사
필요하지 않게되는 여러 폴더를 제거하는 프로세스를 자동화하는 데 도움이되는 기본 폴더를 생각해 냈습니다.
#!/bin/bash
rm -rf ~/myfolder1/$1/anotherfolder
rm -rf ~/myfolder2/$1/yetanotherfolder
rm -rf ~/myfolder3/$1/thisisafolder
이것은 다음과 같이 유발됩니다.
./myscript.sh <{id-number}>
문제는 id-number
(그때처럼) 입력하는 것을 잊으면 정말로 삭제하고 싶지 않은 많은 것을 잠재적으로 삭제할 수 있다는 것입니다.
명령 줄 매개 변수에 모든 형태의 유효성 검사를 추가 할 수있는 방법이 있습니까? 제 경우에는 a) 하나의 매개 변수가 있는지, b) 숫자인지, c) 해당 폴더가 있는지 확인하는 것이 좋습니다. 스크립트를 계속하기 전에.
답변
#!/bin/sh
die () {
echo >&2 "$@"
exit 1
}
[ "$#" -eq 1 ] || die "1 argument required, $# provided"
echo $1 | grep -E -q '^[0-9]+$' || die "Numeric argument required, $1 provided"
while read dir
do
[ -d "$dir" ] || die "Directory $dir does not exist"
rm -rf "$dir"
done <<EOF
~/myfolder1/$1/anotherfolder
~/myfolder2/$1/yetanotherfolder
~/myfolder3/$1/thisisafolder
EOF
편집 : 처음에는 디렉토리가 존재하는지 확인하는 부분을 놓쳐서 스크립트를 완성했습니다. 또한 의견에서 제기 된 문제를 해결했습니다. 정규식 고정로부터 스위치 ==
로 eq
.
내가 말할 수있는 한 이것은 이식 가능한 POSIX 호환 스크립트 여야합니다. 이 때문에 실제로 중요하다 어떤 bashisms, 사용하지 않는 /bin/sh
우분투에 실제로 dash
,이 일하지 bash
.
답변
의 sh
솔루션은 Brian Campbell
고상하고 잘 실행되었지만 몇 가지 문제가 있으므로 나만의 bash
솔루션을 제공 할 것이라고 생각했습니다 .
sh
하나 의 문제 :
- 의 물결표는
~/foo
heredocs 내부의 홈 디렉토리로 확장되지 않습니다. 그리고read
성명 에서 읽 거나 성명에서 인용 할 때도 마찬가지rm
입니다. 즉,No such file or directory
오류가 발생합니다. grep
기본 작업을 위해 분기하는 등은 멍청합니다. 특히 bash의 “무거운”무게를 피하기 위해 엉뚱한 셸을 사용할 때.- 또한 몇 가지 인용 문제를 발견했습니다. 예를 들어 그의
echo
. - 드물지만 솔루션은 줄 바꿈이 포함 된 파일 이름을 처리 할 수 없습니다. (거의 어떤 솔루션도
sh
그것들에 대처할 수 없습니다 -이것이 제가 거의 항상 선호하는 이유bash
입니다. 잘 사용하면 훨씬 더 방탄하고 악용하기 더 어렵습니다).
그렇습니다. /bin/sh
해시 뱅에 사용한다는 것은 어떤 대가를 치르더라도 ISMS를 피해야한다는 것을 의미 하지만, 우분투 또는 정직하고 솔직한 경우에도 원하는 bash
모든 ISMS 를 사용할 수 있습니다.bash
#!/bin/bash
정상에 .
그래서 여기에 bash
더 작고, 더 깨끗하고, 더 투명하고, 아마도 “더 빠르며”더 방탄 한 솔루션이 있습니다.
[[ -d $1 && $1 != *[^0-9]* ]] || { echo "Invalid input." >&2; exit 1; }
rm -rf ~/foo/"$1"/bar ...
- 주위의 따옴표에 주목하십시오
$1
.rm
문! - 다음의
-d
경우에도 검사가 실패합니다.$1
비어 그 하나에 두 개의 검사를, 그래서. - 나는 이유 때문에 정규 표현식을 피했습니다.
=~
bash에서 사용해야하는 경우 정규식을 변수에 넣어야합니다. 어쨌든 저와 같은 glob은 항상 선호되며 훨씬 더 많은 bash 버전에서 지원됩니다.
답변
나는 bash를 사용할 것입니다 [[
.
if [[ ! ("$#" == 1 && $1 =~ ^[0-9]+$ && -d $1) ]]; then
echo 'Please pass a number that corresponds to a directory'
exit 1
fi
이 FAQ 가 좋은 정보 소스 라는 것을 알았습니다 .
답변
위의 답변만큼 방탄하지는 않지만 여전히 효과적입니다.
#!/bin/bash
if [ "$1" = "" ]
then
echo "Usage: $0 <id number to be cleaned up>"
exit
fi
# rm commands go here
답변
사용 set -u
설정되지 않은 인수를 참조 즉시 스크립트를 실패합니다.
답변
test ( man test
) 의 man 페이지 는 bash에서 부울 연산자로 사용할 수있는 모든 연산자를 제공합니다. 다른 프로그래밍 언어에서와 마찬가지로 입력 유효성 검사를 위해 스크립트 (또는 함수) 시작 부분에 이러한 플래그를 사용합니다. 예를 들면 :
if [ -z $1 ] ; then
echo "First parameter needed!" && exit 1;
fi
if [ -z $2 ] ; then
echo "Second parameter needed!" && exit 2;
fi
답변
빈 문자열을 테스트하려면 ‘-z’를 사용하고 디렉토리를 확인하려면 ‘-d를 사용하십시오.
if [[ -z "$@" ]]; then
echo >&2 "You must supply an argument!"
exit 1
elif [[ ! -d "$@" ]]; then
echo >&2 "$@ is not a valid directory!"
exit 1
fi