简体   繁体   English

Shell脚本参数解析

[英]Shell script argument parsing

There are a number of questions about this sort of thing but lets imagine we are targeting a generic Linux system with both getopt and getopts installed (not that we'll use either, but they seem popular) 关于这类事情有很多问题,但我们想象一下我们的目标是安装了getopt和getopts的通用Linux系统(不是我们也会使用它们,但它们似乎很受欢迎)

How do I parse both long (--example | --example simple-option) and short argruments (-e | -esimple-example | -e simple-example) 如何解析long(--example | --example simple-option)和short argruments(-e | -esimple-example | -e simple-example)

You want to use getopt with long and short options. 你想使用带有长和短选项的getopt An example from working code: 工作代码的一个例子:

# Parse arguments
TEMP=$(getopt -n $PROGRAM_NAME -o p:P:cCkhnvVS \
--long domain-password:,pop3-password:\         
,create,cron,kill,help,no-sync-passwords,version,verbose,skip-pop3 \
-- "$@")                                                            

# Die if they fat finger arguments, this program will be run as root
[ $? = 0 ] || die "Error parsing arguments. Try $PROGRAM_NAME --help"       

eval set -- "$TEMP"
while true; do     
        case $1 in 
                -c|--create)
                        MODE="CREATE"; shift; continue
                ;;                                    
                -C|--cron)                            
                        MODE="CRON"; shift; continue  
                ;;                                    
                -k|--kill)                            
                        MODE="KILL"; shift; continue  
                ;;                                    
                -h|--help)                            
                        usage                         
                        exit 0                        
                ;;                                    
                -n|--no-sync-passwords)               
                        SYNC_VHOST=0; shift; continue 
                ;;                                    
                -p|--domain-password)                 
                        DOMAIN_PASS="$2"; shift; shift; continue
                ;;                                              
                -P|--pop3-password)                             
                        POP3_PASS="$2"; shift; shift; continue  
                ;;                                              
                -v|--version)                                   
                        printf "%s, version %s\n" "$PROGRAM_NAME" "$PROGRAM_VERSION"
                        exit 0                                                      
                ;;                                                                  
                -v|--verbose)                                                       
                        VERBOSE=1; shift; continue                                  
                ;;                                                                  
                -S|--skip-pop3)                                                     
                        SKIP_POP=1; shift; continue                                 
                ;;                                                                  
                --)                                                                 
                        # no more arguments to parse                                
                        break                                                       
                ;;                                                                  
                *)                                                                  
                        printf "Unknown option %s\n" "$1"                           
                        exit 1                                                      
                ;;                                                                  
        esac                                                                        
done     

Note, die is a function that was defined previously (not shown). 注意, die是先前定义的函数(未示出)。

The -n option tells getopt to report errors as the name of my program, not as getopt . -n选项告诉getopt报告错误作为我的程序的名称,而不是getopt -o defines a list of short options ( : after an option indicates a needed argument) and --long specifies the list of long options (corresponding in order to the short options). -o定义短选项列表( :在选项表示需要的参数后)和--long指定长选项列表(对应于短选项)。

The rest is just a simple switch, calling shift appropriately to advance the argument pointer. 其余的只是一个简单的开关,适当地调用shift来推进参数指针。 Note, calling shift; shift; 注意,调用shift; shift; shift; shift; is just a die hard habit. 只是一个顽固的习惯。 In the currently modern world, shift 2 would probably suffice. 在当前的现代世界中,第shift 2可能就足够了。

The modern getopt is pretty consistent over newer platforms, however you may encounter some portability problems on older (circa pre Redhat 9) systems. 现代getopt在新平台上非常一致,但是在旧版(大约在Redhat 9之前的系统)上可能会遇到一些可移植性问题。 See man getopt for information about backwards compatibility. 有关向后兼容性的信息,请参阅man getopt However it's unlikely that you'll run into the need for it. 但是,你不太可能遇到它的需要。

Finally, after parsing options, you can once again call: 最后,在解析选项后,您可以再次调用:

eval set -- "$@"

This will move the argument pointer to anything else left on the command line after getopt was done parsing options. 这将在getopt完成解析选项后将参数指针移动到命令行上剩下的任何内容。 You can then just shift to keep reading them. 然后你可以shift继续阅读它们。 For instance, if a command looked like this: 例如,如果命令看起来像这样:

./foo --option bar file1.txt file2.txt file3.txt

Don't forget to make a handy -h / --help option to print your new fancy options once you're done. 一旦完成,不要忘记制作一个方便的-h / --help选项来打印新的花哨选项。 :) If you make that output help2man friendly, you have an instant man page to go with your new tool. :)如果你使输出help2man友好,你有一个即时手册页与你的新工具。

Edit 编辑

On most distributions, you can find more example getopt code in /usr/share/doc/util-linux/examples , which should have been installed by default. 在大多数发行版中,您可以在/usr/share/doc/util-linux/examples找到更多示例getopt代码,这些代码应默认安装。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM