두 개의 스위치 -h와 -d를 사용하여 스크립트를 만들려고 합니다. -d에는 필수 숫자 인수가 있습니다. 그 뒤에는 결정되지 않은 수의 파일 경로가 있습니다. 지금까지 이것을 가지고 있지만 코드가 잘못된 스위치 -r(어떤 이름이든 가능)을 인식하지 못하는 것 같고 스위치를 입력하지 않으면 작동하지 않습니다.
while getopts ":hd:" opt; do
case $opt in
h)
echo $usage
exit 0
;;
d)
shift 2
if [ "$OPTARG" -eq "$OPTARG" ] ; then # ako dalsi argument mame cislo
depth=$OPTARG
fi
;;
\?)
shift 1
;;
:)
shift 1
;;
esac
done
echo $1
을 입력하면 ./pripravne1.sh -d /home/OS/test_pz/test2
다음이 표시됩니다 ./pripravne1.sh: [: /home/OS/test_pz/test2: integer expression expected
. 입력하면 ./pripravne1.sh -r /home/OS/test_pz/test2
빈 문자열만 표시됩니다.
답변1
[ "$OPTARG" -eq "$OPTARG" ] ...
$OPTARG
숫자인지 확인하는 올바른 방법이 아닙니다 . 숫자가 아닌 경우 사용자에게 짜증나는 이해할 수 없는 오류가 인쇄되거나 반환될 수 있습니다.진짜모든 경우(in ksh
)에서 true를 반환하거나 null $OPTARG
(in )에 대해서도 zsh
true를 반환합니다 .
또한 인자를 받아들이는 옵션을 or -d12
형태로 줄 수 있기 -d 12
때문에 블라인드 인젝션이 shift 2
잘리지 않는다. shift
루프 내부에서 실행하면 루프 getopts
자체가 실시간 매개변수 목록을 사용하므로 심각한 상호 작용이 있을 수 있습니다.
이를 염두에 두고 내 조언은 다음과 같습니다.
die(){ echo >&2 "$@"; exit 1; }
usage(){ echo >&2 "usage: $0 [-h] [-d num] files..."; exit 0; }
depth=0
while getopts :hd: opt; do
case $opt in
h) usage ;;
d) case $OPTARG in
''|*[!-0-9]*|-|*?-*) die "invalid number $OPTARG" ;;
*) depth=$OPTARG ;;
esac
;;
:) die "argument needed to -$OPTARG" ;;
*) die "invalid switch -$OPTARG" ;;
esac
done
shift "$((OPTIND - 1))"
echo depth="$depth"
echo files="$@"
답변2
단일 대괄호는 [
posix 표준을 따르지만 [[
일반적으로 bash에서 사용할 수 있는 것보다 사용하기가 더 어렵습니다. 단일 대괄호 표준에서는 -eq
문자열이 아닌 정수에만 작동합니다. 예를 들어, 다음은 잘 작동합니다: if [ "2" -eq "2" ] ; then echo foo; fi
. 이중 대괄호( -eq
문자열 허용) 또는 =
단일 대괄호 형식을 사용할 수 있습니다.
if [ "bar" = "bar" ] ; then echo foo; fi
확인하다https://ryanstutorials.net/bash-scripting-tutorial/bash-if-statements.php 테스트 및 테스트가 필요한 경우 POSIX에 대한 정보http://tldp.org/LDP/abs/html/testconstructs.html((
및 와 같은 다양한 유형의 테스트 구조에 대한 정보입니다 [[
.