개발 중인 스크립트에 대해 두 개의 매개변수와 세 번째 선택적 매개변수를 사용하고 싶습니다. 나는 bash를 처음 접했기 때문에 내가 원하는 것을 수행하는 다음 코드를 복사하고 이해하려고 노력했습니다.
while [[ $# -gt 0 ]]; do
case $1 in
-f1|-fasta1)
FASTA1=$2
shift
;;
-f1=*|-fasta1=*)
FASTA1=${1#*=}
;;
-d|-directory)
DIRECTORY=$2
shift
;;
-d=*|-directory=*)
DIRECTORY=${1#*=}
;;
-f2|fasta2)
FASTA2=$2
shift
;;
-f2=*|-fasta2=*)
FASTA2=${1#*=}
;;
-*)
echo "Invalid option: $1" >&2
exit 1
;;
--)
# Do FILES+=("${@:2}") maybe
break
;;
*)
# TODO
# Do FILES+=("$1") maybe
;;
esac
shift
done
문제는 이 코드에는 코드가 무엇인지 이해하지 못하는 부분이 많다는 것입니다. 예를 들어, -gt
또는 1#*=
각 매개변수를 첫 번째 줄에 두 번 써야 하는 이유는 무엇입니까?
-f1|-fasta1)
FASTA1=$2
shift
그리고 두
-f1=*|-fasta1=*)
FASTA1=${1#*=}
누군가 이에 대한 설명을 어디서 찾을 수 있는지 말해 줄 수 있습니까? 나는 튜토리얼을 읽었지만 더 간단한 예제로는 이것을 이해할 수 없습니다.
답변1
게시한 코드는 실제로 명령줄 인수를 구문 분석하는 매우 "수동" 방법입니다. 일반적으로 이러한 목적으로 사용 getopt
및/또는 제공하는 getopt_long
것이 좋은 관행으로 간주됩니다 . 또한 -fasta1
하나의 대시로 "긴 옵션"(예: )을 도입하는 것은 일반적으로 앞에 두 개의 대시가 올 것으로 예상합니다.이 문제명령줄 매개변수 형식 정보)
즉, 여러분이 보는 대부분의 내용은 기본 쉘 구문입니다.문자열 연산,case
성명그리고테스트 구조.
이 명령문은 특수 인수, 즉 명령줄 인수의 수를 취하고 그 값이 0보다 큰지( ) 확인하는 [[ $# -gt 0 ]]
테스트일 뿐입니다 . 인수 처리 루틴은 처리 후 첫 번째 명령줄 인수를 삭제하여 인수 수를 지속적으로 줄이는 문을 사용하기 때문에 이는 루프의 조건 으로 사용됩니다 . 모든 매개변수가 처리된 후 옵션 처리 루프가 완료되어야 합니다.$#
-gt
while
shift
다른 질문에 관해서: 프로그램은 사용자가 가능한 구문 변수에서 첫 번째 FASTA 파일을 지정할 수 있도록 허용하려고 합니다. 즉:
-f1 <filename>
-fasta1 <filename>
-f1=<filename>
-fasta1=<filename>
프로그램은 명령줄 인수를 "수동으로" 반복하여 이를 수행합니다. 즉, 항상 "현재 첫 번째" 인수( $1
)가 무엇인지 확인하고 이를 해석한 다음 shift
명령을 사용하여 이를 삭제합니다(여기서 모든 명령줄 인수는 "위로 이동됩니다"). 하나" 비트").
"짧은" 및 "긴" 옵션 이름을 허용하기 위해 명령문은 and (공백으로 구분된 구문의 경우) 및 and ( --구분된 구문의 경우)를 현재 인수로 case
허용합니다 . 그러나 구문에 따라 옵션의 "값" 부분을 다르게 처리해야 합니다.-f1
-fasta1
-f1=*
-fasta1=*
=
- 공백으로 구분된 구문의 경우 첫 번째 FASTA 파일의 명령문은
$1
또는 로-f1
식별됩니다-fasta1
. 프로그램은 옵션의 "값"이 다음 명령줄 인수에 있다는 것을 알고 있으므로 해당 내용을 변수 에$2
할당합니다 . 이 반복에서 이미 처리되었으므로 다음 명령줄 인수를 삭제하려면 추가 인수가 필요합니다 .$2
FASTA1
shift
- -separated 구문 의 경우
=
첫 번째 FASTA 파일의 명령문은$1
또는 일치 로-f1=*
식별됩니다-fasta1=*
. 이는 옵션의 "값"이 현재 값의 일부이며$1
문자열 조작을 통해 추출되어야 함을 의미합니다. 성명서
"값을 반환${variablename#pattern}
$variablename
하지만 가장 짧은 일치 문자열을 제거함을 의미합니다.pattern
처음부터가치". 그래서,
"값을 반환하지만${1#*=}
$1
처음부터 가장 짧은 일치 문자열을 제거"를 의미하며 값에서 또는 을 효과적으로 제거합니다. 이제 남은 것은 파일 이름뿐입니다.*=
-f1=
-fasta1=
쉘 프로그래밍에 대해 더 자세히 알고 싶다면 다음을 추천합니다.GreyCat&Lhunath의 배쉬 가이드추가 읽기를 위해.