[첫화면으로]Perl/Getopt-Long

마지막으로 [b]

Getopt::Long 코어 모듈

1. perldoc Getopt::Long 정리
1.1. 개요
1.2. 설명
1.3. 명령행 옵션 개요
1.4. Getopt::Long 시작하기
1.4.1. 간단한 옵션들
1.4.2. 조금 덜 간단한 옵션들
1.4.3. 옵션과 다른 인자들이 섞인 경우
1.4.4. 값을 받는 옵션들
1.4.5. 값이 여러 개인 옵션들
1.4.6. 해쉬 값으로 된 옵션들
1.4.7. 사용자 정의 서브루틴으로 옵션 처리하기
1.4.8. 이름이 여러 개인 옵션
1.4.9. 대소문자와 축약형
1.4.10. 옵션 명세 요약
1.5. 고급
1.5.1. 객체 지향 인터페이스
1.5.2. 쓰레드 안전
1.5.3. 문서화와 도움말
1.5.4. 임의의 배열로부터 옵션 추출
1.5.5. 임의의 문자열로부터 옵션 추출
1.5.6. 옵션 값들을 하나의 해쉬에 저장
1.5.7. 번들링
1.5.8. 단일 대쉬
1.5.9. 인자 콜백
1.6. Getopt::Long 설정하기
1.7. export 가능한 메쏘드
1.8. 리턴값과 에러
1.9. Legacy
1.9.1. 디폴트 옵션 변수
1.9.2. 옵션 시작 문자 대체
1.9.3. 설정 변수
1.10. 팁과 테크닉
1.10.1. 다수의 값을 해쉬 옵션에 차례로 저장하기
1.11. 문제 해결
1.11.1. 옵션을 주지 않았을 때 거짓을 반환하지 않아요!
1.11.2. 명령행에 적은 내용을 올바르게 분리하지 않아요
1.11.3. "Undefined subroutine &main::GetOptions called" 에러가 나요
1.11.4. "-?" 옵션을 넣으려면 어떻게 해야 하나요
2. 기타 & Comments

1. perldoc Getopt::Long 정리

Perldoc:Getopt::Long 내용 정리

1.1. 개요

use Getopt::Long;
my $data = "file.dat";
my $length = 24;
my $verbose;
$result = GetOptions ("length=i" => \$length,  # numeric
                      "file=s" => \$data,      # string
                      "verbose" => \$verbose); # flag

1.2. 설명

명령행 옵션을 처리하는 POSIX 문법과 GNU 확장을 지원하는 GetOptions() 함수 구현

1.3. 명령행 옵션 개요

전형적인 옵션들의 형태:

1.4. Getopt::Long 시작하기

1.4.1. 간단한 옵션들

값이 없는 옵션들
예:    --all --verbose --quiet --debug

    my $verbose = '';   # 기본값을 false로 설정한 옵션 변수
    my $all = '';       # option variable with default value (false)
    GetOptions ('verbose' => \$verbose, 'all' => \$all);
                ^^^^^^^^^               ^^^^^    <-- 이 부분을 옵션 명세라 부름

@ARGV 에 있는 인자들 중에 해당 옵션이 있다면 변수의 값을 1로 설정. 없다면 아무 일도 안 함.

GetOptions은 명령행 처리가 성공하면 참을 반환. 그렇지 않을 경우 STDERR에 에러메시지를 출력한후 거짓 반환.

1.4.2. 조금 덜 간단한 옵션들

부정할 수 있는 (negatable) 옵션
    my $verbose = '';   # option variable with default value (false)
    GetOptions ('verbose!' => \$verbose);

증가할 수 있는 (incremental) 옵션
    my $verbose = '';   # option variable with default value (false)
    GetOptions ('verbose+' => \$verbose);

1.4.3. 옵션과 다른 인자들이 섞인 경우

기본적으로 Getopt::Long 은 옵션과 그 외 인자들이 섞여 있어도 옵션 부분만 추출해낸다. 대쉬 두 개 --를 적어주면 Getopt::Long은 그 뒷부분의 인자를 처리하지 않는다.
   --size 24 -- --all

1.4.4. 값을 받는 옵션들

    my $tag = '';       # option variable with default value
    GetOptions ('tag=s' => \$tag);

1.4.5. 값이 여러 개인 옵션들

하나의 옵션이 여러 개의 값을 받는 경우
예:    --library lib/stdlib --library lib/extlib

    GetOptions ("library=s" => \@libfiles);
    GetOptions ("library=s@" => \$libfiles);

여러 개의 값을 쉼표로 구분하여 받도록 하는 코드:2
    GetOptions ("library=s" => \@libfiles);
    @libfiles = split(/,/,join(',',@libfiles));

(실험적인 기능)

한 번에 여러 개의 값을 받도록 하는 경우 (공백으로 구분)
예:    --coordinates 52.2 16.4 --rgbcolor 255 255 149
    GetOptions('coordinates=f{2}' => \@coor, 'rgbcolor=i{3}' => \@color);

1.4.6. 해쉬 값으로 된 옵션들

옵션을 저장할 곳이 해쉬의 레퍼런스인 경우, 키=값 형태의 문자열을 값으로 받아들인 후에 해쉬에 저장한다.
    GetOptions ("define=s" => \%defines);
    GetOptions ("define=s%" => \$defines);

예:    --define os=linux --define vendor=redhat

1.4.7. 사용자 정의 서브루틴으로 옵션 처리하기

옵션을 저장할 곳으로 서브루틴의 레퍼런스나 익명 서브루틴을 지정할 수 있다. 해당 옵션이 있을 경우 GetOptions()는 그 서브루틴을 호출하며, 인자 두 개 또는 세 개를 넘긴다.

두 옵션이 서로 연관되어 있는 예:
    my $verbose = '';   # option variable with default value (false)
    GetOptions ('verbose' => \$verbose,
                'quiet'   => sub { $verbose = 0 });

1.4.8. 이름이 여러 개인 옵션

사용자 편의를 위해, 옵션에 연상하기 쉬운 이름 여러 개를 동시에 부여:
   GetOptions ('length|height=f' => \$length);

1.4.9. 대소문자와 축약형

별도로 설정하지 않은 경우 GetOptions()는

예:
    GetOptions ('length|height=f' => \$length, "head" => \$head);

1.4.10. 옵션 명세 요약

각 옵션 명세는 두 부분으로 나뉜다: 이름 명세 부분과 인자 명세 부분

이름 명세 부분에는 옵션의 이름과, 추가적으로 별칭들이 세로선으로 구분되어 나열된다.
   length          옵션 이름은 "length"
   length|size|l   이름은 "length", 별칭은 "size"와 "l"

인자 명세 부분은 다음과 같은 것들이 올 수 있다:

1.5. 고급

1.5.1. 객체 지향 인터페이스

객체지향 방식으로 사용:
    use Getopt::Long;
    $p = new Getopt::Long::Parser;
    $p->configure(...configuration options...);
    if ($p->getoptions(...options descriptions...)) ...

옵션 설정을 객체 생성할 때 할 수도 있음
    $p = new Getopt::Long::Parser
             config => [...configuration options...];

1.5.2. 쓰레드 안전

Getopt::Long 은 Perl 5.8의 ithreads 를 사용하는 경우는 쓰레드 안전하다. 5.005에 추가되었던 오래된 쓰레드 구현을 사용할 경우는 그렇지 않다.

1.5.3. 문서화와 도움말

도움말 메시지를 출력하는데 Perldoc:Pod::Usage를 사용하도록 권장함: Pod::Usage 문서를 참조7

    use Getopt::Long;
    use Pod::Usage;

    my $man = 0;
    my $help = 0;

    GetOptions('help|?' => \$help, man => \$man) or pod2usage(2);
    pod2usage(1) if $help;
    pod2usage(-exitstatus => 0, -verbose => 2) if $man;

    __END__

    =head1 NAME

    sample - Using Getopt::Long and Pod::Usage

    =head1 SYNOPSIS

    sample [options] [file ...]

     Options:
       -help            brief help message
       -man             full documentation

    =head1 OPTIONS

    =over 8

    =item B<-help>

    Print a brief help message and exits.

    =item B<-man>

    Prints the manual page and exits.

    =back

    =head1 DESCRIPTION

    B<This program> will read the given input file(s) and do something
    useful with the contents thereof.

    =cut

1.5.4. 임의의 배열로부터 옵션 추출

GetOptionsFromArray함수를 사용하여, @ARGV 전역 배열이 아닌 임의의 배열에서 옵션 추출할 수 있다.
    use Getopt::Long qw(GetOptionsFromArray);
    $ret = GetOptionsFromArray(\@myopts, ...);

아래 두 줄은 동일한 동작을 한다:
    $ret = GetOptions( ... );
    $ret = GetOptionsFromArray(\@ARGV, ... );

1.5.5. 임의의 문자열로부터 옵션 추출

GetOptionsFromString 함수를 사용하여 임의의 문자열로부터 옵션을 추출할 수 있다.

    use Getopt::Long qw(GetOptionsFromString);
    $ret = GetOptionsFromString($string, ...);

처리되지 않고 남는 인자가 있을 수 있음
   ($ret, $args) = GetOptionsFromString($string, ... );

1.5.6. 옵션 값들을 하나의 해쉬에 저장

옵션이 많을 경우 각각을 개별적인 변수에 저장하는 건 불편하므로, 하나의 해쉬에 옵션값들을 저장할 수 있다.
    my %h = ();
    GetOptions (\%h, 'length=i');       # $h{length}에 저장됨

리스트나 해쉬값을 받는 옵션의 경우는 타입 뒤에 @%를 붙여서 명시해야 함:
    GetOptions (\%h, 'colours=s@');     # @{$h{colours}}에 저장됨

옵션값이 실제로 저장될 변수의 레퍼런스를 해쉬에 담을 수도 있음:
    my $len = 0;
    my %h = ('length' => \$len);
    GetOptions (\%h, 'length=i');       # $len에 저장됨

# 위 코드는 아래와 동일
    my $len = 0;
    GetOptions ('length=i' => \$len);   # $len에 저장됨

자주 사용되는 옵션은 각각의 변수에 저장하고 나머지 옵션은 하나의 해쉬에 저장하는 식으로도 사용 가능하다:
    my $verbose = 0;                    # 자주 참조됨
    my $debug = 0;                      # 자주 참조됨
    my %h = ('verbose' => \$verbose, 'debug' => \$debug);
    GetOptions (\%h, 'verbose', 'debug', 'filter', 'size=i');
    if ( $verbose ) { ... }
    if ( exists $h{filter} ) { ... option 'filter' was specified ... }

1.5.7. 번들링

첫번째 단계
    Getopt::Long::Configure ("bundling");

두번째 단계
   Getopt::Long::Configure ("bundling_override");

옵션 값들도 합쳐서 표시 가능

번들링을 가능하게 설정할 경우, 단일 문자 옵션은 대소문자를 구별하고 긴 옵션은 구별하지 않는다. 단일 문자 옵션들도 대소문자를 구분하지 않게 하려면 다음과 같이 설정:
    Getopt::Long::Configure ("bundling", "ignorecase_always");

1.5.8. 단일 대쉬

    GetOptions ('' => \$stdio);

1.5.9. 인자 콜백

    my $width = 80;
    sub process { ... }
    GetOptions ('width=i' => \$width, '<>' => \&process);
위처럼 작성한 상황에서 명령행 인자를 아래와 같이 줄 경우, 다음과 같은 순서대로 처리된다.
    arg1 --width=72 arg2 --width=60 arg3

1.6. Getopt::Long 설정하기

Getopt::Long::Configure()를 사용하여 Getopt::Long의 동작을 설정할 수 있음

또는,2.24부터는 use 구문에서 설정 옵션을 전달할 수 있음:
    use Getopt::Long qw(:config no_ignore_case bundling);

사용 가능한 옵션들:
    using argument               sets option(s)
    ------------------------------------------
    -a, --a                      a
    -l, --l                      l
    -al, -la, -ala, -all,...     a, l
    --al, --all                  all

1.7. export 가능한 메쏘드

VersionMessage

HelpMessage

위 두 함수는 GetOptions()에서 직접 지정할 수 없음. 익명 서브루틴 안에 넣어서 사용하라9
   GetOptions("version" => \&VersionMessage);         # 이렇게 쓰지 말고
   GetOptions("version" => sub { VersionMessage() }); # 이렇게 사용

   GetOptions("help" => \&HelpMessage);               # 이렇게 쓰지 말고
   GetOptions("help" => sub { HelpMessage() });       # 이렇게 사용

1.8. 리턴값과 에러

설정 과정이나 옵션을 정의할 때 에러가 발생할 경우 die()를 통해 에러를 알리고 프로그램은 종료된다.

GetOptions()은 성공적으로 수행될 경우 참을 반환. 옵션 추출 과정에서 에러가 발생하면 에러 내용을 warn()을 통해 경보하고 거짓을 반환한다.

1.9. Legacy

Perl4의 newgetopt.pl 시절 제공되었다가 하위호환성 유지를 위해 여전히 제공되는 기능들.

1.9.1. 디폴트 옵션 변수

옵션값 저장위치를 지정하지 않을 경우는 opt_XXX(XXX는 옵션의 주이름)라는 전역변수에 옵션값을 저장함.
   our $opt_length = 0;
   GetOptions ('length=i'); # $opt_length 에 저장됨

   GetOptions ("size=i", "sizes=i@");
   $opt_size = 10;
   @opt_sizes = (24, 48);

1.9.2. 옵션 시작 문자 대체

옵션 이름 앞에 적는 문자("-"와 같은)를 다른 것을 사용하고 싶을 경우 그 문자를 첫번째 인자(또는 해쉬 레퍼런스 인자 바로 뒤에 두번째 인자)로 전달

    my $len = 0;
    GetOptions ('/', 'length=i' => $len);
사용예:     /length 24 -- arg

1.9.3. 설정 변수

Getopt::Long 구버전에서는 동작 설정을 위해 변수를 사용했었음. 현재도 가능하나, Configure를 사용할 것을 강력하게 권장함

1.10. 팁과 테크닉

1.10.1. 다수의 값을 해쉬 옵션에 차례로 저장하기

해쉬와 배열의 장점을 결합하여, 명령행이 다음과 같을 때
  --list add=first --list add=second --list add=third
각각의 'list add'의 값이 배열 레퍼런스 $list->{add} 에 차례로 저장되어 다음과 같이 결과가 나오게 하고 싶은 경우:
  $list->{add} = [qw(first second third)];
옵션 저장지를 다음 서브루틴으로 하여 구현가능:
  GetOptions('list=s%' =>
               sub { push(@{$list{$_[1]}}, $_[2]) });

1.11. 문제 해결

1.11.1. 옵션을 주지 않았을 때 거짓을 반환하지 않아요!

그것이 'options'라 불리는 이유입니다.

1.11.2. 명령행에 적은 내용을 올바르게 분리하지 않아요

명령행을 분리하는 건 GetOptions가 아니라 명령행 인터프리터(CLI)입니다. Unix에서는 shell, 윈도우에서는 COMMAND.COM또는 CMD.EXE, 다른 운영체제에서는 또다른 CLI가 있죠.

명령행에 특수 문자, 특히 따옴표나 백슬래쉬가 포함된 경우, CLI들의 동작이 서로 다를 수 있다는 점이 중요합니다. 예를 들어 Unix 쉘에서는 작은따옴표(')나 큰따옴표(")를 사용해 단어들을 하나의 그룹으로 묶을 수 있습니다. 다음 세 가지는 Unix에서 다 동일한 의미입니다:
    "two words"
    'two words'
    two\ words

잘 모르겠으면, 다음 구문을 당신의 펄 프로그램 앞에 삽입해서 당신이 사용 중인 CLI가 인자를 어떻게 프로그램에 넘겨주는지를 검증하세요:
   print STDERR (join("|",@ARGV),"\n");

1.11.3. "Undefined subroutine &main::GetOptions called" 에러가 나요

MS윈도우를 사용중이고, 다음과 같이 적지 않았나 보세요: (대문자 'O')
   use GetOpt::Long;

1.11.4. "-?" 옵션을 넣으려면 어떻게 해야 하나요

Getopt::Long 버전이 2.13이상이어야 하고, 별칭으로만 넣을 수 있습니다:
    use Getopt::Long;
    GetOptions ("help|?");    # -help 또는 -? 옵션 둘 다 $opt_help를 세팅

2. 기타 & Comments

이름:  
Homepage:
내용:
 


컴퓨터분류 Perl
각주:
1. 그냥 배열의 레퍼런스를 써도 됨. 스칼라 레퍼런스를 사용할 경우, 옵션을 주지 않으면 디레퍼런스할 때 경고가 뜨니, 초기값을 [] 등으로 미리 빈 익명 배열로 할당하는 게 좋겠다.
2. 일단 join으로 합친 후 다시 분리하는 이유는, --library aa,bb --library cc 이런 식으로 쓰는 경우도 처리하기 위함인 듯
3. 배열과 마찬가지로 여기서도 그냥 해쉬 레퍼런스를 사용해도 됨
4. GetOptions()에서 서브루틴을 호출하는 경우에도 마찬가지. 첫번째 인자에는 항상 주이름이 들어간다
5. 즉 스칼라 레퍼런스로 지정되었을 때만
6. 옵션 이름만 있고 뒤에 값이 없을 때 얘기이다. 옵션 자체가 없을 경우는 변수에 아무 것도 할당되지 않는다
7. /Pod-Usage
8. 즉 옵션 이름과 등호는 있는데 값이 적혀 있지 않은 경우
9. 그런데 실제로 해보면 딱히 안 되는 것 같지 않다...

마지막 편집일: 2021-7-2 2:34 pm (변경사항 [d])
5291 hits | Permalink | 변경내역 보기 [h] | 페이지 소스 보기