여러 플래그가 있는 스크립트

여러 플래그가 있는 스크립트

소문자/대문자 파일이나 디렉터리를 생성하는 스크립트를 생성하려고 합니다.

 modify [-r] [-l|-u] <dir/file names...>

현재 플래그를 확인하기 위해 getopts를 사용하고 있습니다. 그러나 -rl 수정과 같은 명령을 실행하여 내 디렉터리/파일을 반복적으로 소문자로 바꿀 수는 없습니다.

(편집된) 코드:

#!/bin/bash

FLAGS=""
if [ $# -eq 0 ]
then
    echo -e "No arguments supplied. \nPlease supply an argument.For more information use -h."
else
  while getopts "rluh" opt
  do
    case $opt in
      r)
        FLAGS+=r
        ;;
      l)
        FLAGS+=l
        ;;
      u)
        FLAGS+=u
        ;;
      h)
        FLAGS+=h
        ;;
      *)
        echo "Unrecognized argument. Please enter -h for information"
    esac
  done

fi
if [[ "$FLAGS" == "l" && "$2" -eq 0 ]]
then
  echo "file to modify $2"
elif [[ "$FLAGS" == "h" && "$2" -eq 0 ]] 
then
  echo "Some info"
fi


exit 0

답변1

활성화된 각 옵션에 대해 별도의 플래그를 설정하면 특정 옵션이 사용되는지 확인하기 위해 다른 문자열을 구문 분석할 필요가 없으므로 더 쉬울 것입니다.

예를 들어:

#!/bin/bash

self=$0

show_help () {
    cat <<END_HELP
Usage: $self [-r] [-l|-u] pathname [...]

Options:

    info about options here

END_HELP
}

recurse=0    # don't recurse by default
lowercase=1  # lowercase by default

while getopts rluh opt; do
    case $opt in
        r) recurse=1   ;;
        l) lowercase=1 ;;
        u) lowercase=0 ;;
        h) show_help
           exit ;;
        *) echo 'Error in parsing options' >&2
           exit 1
    esac
done

shift "$(( OPTIND - 1 ))"

for pathname do
    if [ -d "$pathname" ] && [ "$recurse" -eq 1 ]; then
        # recurse here
    fi
    if [ "$lowercase" -eq 1 ]; then
        # turn into lowercase
    else
        # turn into uppercase
    fi
done

다음 코드는 shift샘플 코드일 뿐입니다. 재귀 대신 루프 사용을 고려하는 것이 좋습니다 find(아마도 모든 경우에 recursion플래그가아니요놓다).

그런데 shift구문 분석된 모든 옵션이 제거되어 "$@"경로 이름 피연산자만 위치 인수 목록에 남게 됩니다. 이것이 루프 이후에 반복되는 것입니다.

위에 작성된 코드는 적절한 기본값을 사용합니다(이는 도움말 텍스트에 언급되어야 합니다). 이는 스크립트를 실행하는 데 옵션이 필요하지 않음을 의미합니다. 참고로 도구를 실행하세요.아니요어떤 매개변수로도 오류가 발생하지 않을 수 있습니다. 해야 할 일이 없으므로, 어떤 일도 해서는 안 됩니다.

답변2

플래그 문자를 단일 문자열로 연결하므로 을 사용하면 을 myscript -l -r얻 거나 와 FLAGS=lr같지 않습니다 .lr

동일성 테스트 대신 패턴 일치를 사용하여 이를 처리할 수 있습니다.

if [[ $FLAGS = *r* ]]; then
    echo "flag -r was given"

또는 각 플래그에 대해 다른 변수를 추가합니다.

r_flag=
l_flag=
while getopts "rluh" opt; do
    case $opt in
        r) r_flag=1;;
...
if [[ $r_flag ]]; then
    echo "flag -r was given"

어떤 경우든, ...에 의해 처리된 옵션이 위치 인수에서 제거되고 ...에 남은 것은 옵션 뒤에 제공된 스크립트 인수가 되도록 루프 shift $(( OPTIND - 1 ))후에 실행하기 를 원할 가능성이 높습니다 .while getoptsgetopts$1$2

답변3

이와 같은 것은 FLAGS+=rFLAGS에 r을 추가합니다. 따라서 modify -r -lFLAGS의 경우 rl. 각 옵션에는 하나의 변수( FLAG_r)를 사용해야 합니다.

스크립트가 "$2" -eq 0두 개의 디렉토리 이름을 얻는 경우에만(두 번째 이름은 입니다 0. 더 나은 비교는 입니다 "$2" = "".

관련 정보