2012-10-31 3 views
0

-c-f 각각에 옵션이 필요한 스크립트를 작성하고 싶습니다. 내 스크립트를 실행하면 내가 예기치 않은 오류를 얻을 아래왜이 인수는 구문 분석 오류입니까?

: 첫 번째 경우

$ ./user.sh -c 
./user.sh: option requires an argument -- c 

Usage: user.sh -c username -f filename 
    -c username 
    -f SSH public key 

$ ./user.sh -c gg 
Error: You have not given a filename. 

을, 나는 내가 -c의 옵션을 잃었 그리고 두 번째 경우에 내가 좋아했을 것이라고 말했다 좋아했 그것은 내가 누락되었다고 말했다 -f.

질문

어떻게 같은 오류 나눠을해야합니까, 내가 무슨 일을하고 있는가?

user.sh

#!/bin/bash                        

usage() { 
    echo "Usage: user.sh -c username -f filename" 
    echo " -c username" 
    echo " -f SSH public key" 
    echo "" 
} 

if ! [ "$*" ]; then 
    usage 
    exit 1 
fi 

while getopts "c:f:" opt; do 
    case $opt in 
     c) user=$OPTARG;; 
     f) filename=$OPTARG;; 
     \?) 
      echo 
      usage 
      exit 1;; 
     *) echo "Internal error: Unknown option.";; 
    esac 
done 

if ! [ $filename ]; then 
    echo "Error: You have not given a filename." 
    exit 1 
fi 

if ! [ $user ]; then 
    echo "Error: You have not given an username." 
    exit 1 
fi 

답변

3

c: '는 -c 옵션이 사용자 이름이 와야합니다'라고.

오류 메시지에 '-c 옵션 뒤에 사용자 이름이 없습니다.'라는 메시지가 표시됩니다.

'사용자 이름'은 언급하지 않았지만 그 내용이 무엇인지 알지 못하기 때문에 '-c'옵션을 따르고 있습니다.

내장형 getopts은 필수 옵션을 처리 할 수 ​​없습니다. 필수 옵션이 실제로 전달되었는지 확인하여 직접 코딩해야합니다. 동일한 옵션이 두 번 지정되면 걱정하지 않아도됩니다. 당신의 코드는 중요하다면 그것을 다루어야합니다. (마지막으로 지정한 값을 적용하는 것은 쉽습니다.)

현대식 스타일은 필수 인수 앞에 옵션 문자를 사용하지 않는 것입니다. 나는 전적으로 변화에 찬성하지 않습니다. 그것은 다음에 나오는 것을 가리키는 옵션 문자를 사용하는 방식에서 인수의 순서가 중요하게된다는 것을 의미합니다. ./user.sh username filename을하지만, 옵션 문자와 함께, 당신은이 중 하나를 작성하고 그것을 작동 것으로 예상 할 수있다 : 옵션 문자가 없으면 쓸 거라고 너무 여분의 인수에 대해 걱정에 무거운 짐이라고

./user.sh -c username -f filename 
./user.sh -f filename -c username 

참고.

shift $(($OPTIND - 1)) 

이 처리 된 인수를 제거하기 위해, 당신은 할 수 있습니다 : 당신은 일반적으로 사용하는 것 그 주제에

case "$#" in 
(0) : No extra arguments - OK;; 
(*) echo "$0: Too many arguments" >&2; exit 1;; 
esac 

그리고 변화를. 오류 보고서는 표준 출력이 아닌 표준 오류로 보내집니다. >&2 리디렉션은 표준 출력 (파일 설명자 1)을 표준 오류 (파일 설명자 2)로 보냅니다.

모호성을 피하기 위해, 나는 조금 다르게 사용 기능을 코딩 할 것 :

usage() 
{ 
    { 
    echo "Usage: user.sh -c username -f filename" 
    echo " -c username Name of user to connect as" 
    echo " -f filename SSH public key file" 
    echo "" 
    } >&2 
} 

내부 중괄호 내가 할/O 리디렉션을 한꺼번에, 서브 쉘을 시작하지 않고. 이는 같은 위치에 여러 개의 echo 명령을 보내야 할 때 유용 할 수 있습니다. 나는 또한 세부 정보를 약간 다르게 제시 했으므로 사용자가 'SSH 공개 키'가 -f을 따르는 세 가지 인수라고 생각하도록 혼동하지 않도록하십시오.순수 옵션 플래그가있는 경우 공백이옵니다.

echo " -V    Print version information and exit" 
+0

고마워요. '--help' 출력을 쓰는 표준을 알고 있습니까? 예 : 몇 개의 공백이 있어야하며 필수 및 선택 인수와 옵션을 나타낼 수 있습니까? –

+1

요약 행에서 옵션 항목은 대괄호로 묶여 있으며 필수 항목은'cmd [-ov] -c username -f filename'입니다. '충분 함'을 넘어 공백에 대한 표준은 없습니다. 예제에서는 4를 사용했습니다. 충분하다. 2는 아마도 약간의 분리를 제공하는 최소값 일 것입니다. 그렇지 않으면, 탐험 ... 다양한 명령을'--help'로 실행하고 그들이하는 일을보십시오. 일부는 다른 것보다 길다. –

관련 문제