Linux 使用Getopts传递多个强制标志的问题

Linux 使用Getopts传递多个强制标志的问题,linux,bash,ubuntu,find,getopts,Linux,Bash,Ubuntu,Find,Getopts,我目前正在编写一个脚本,我很难用带有强制参数的多个标志来概括我的想法。为了简洁起见,我将其缩小为两个选项(尽管它仍然很长) 如果我只使用两个标志中的一个来运行命令,它运行得很好。我正在用管道连接wc-l进行测试。为清楚起见,我将使用系统显示的文件和目录数量: ./testfind.sh -f /home | wc -l #WORKS FINE, puts out a count of 342 ./testfind.sh -d /home | wc -l

我目前正在编写一个脚本,我很难用带有强制参数的多个标志来概括我的想法。为了简洁起见,我将其缩小为两个选项(尽管它仍然很长)

如果我只使用两个标志中的一个来运行命令,它运行得很好。我正在用管道连接wc-l进行测试。为清楚起见,我将使用系统显示的文件和目录数量:

./testfind.sh -f /home | wc -l            #WORKS FINE, puts out a count of 342
./testfind.sh -d /home | wc -l            #WORKS FINE, puts out a count of 1996
./testfind.sh -d /home -f /home | wc -l   #WORKS FINE, puts out count of 2338, (total of d and f)
现在这是1和2的旗帜

./testfind.sh -df /home | wc -l           #FAILS, RUNS FIRST FLAG BUT NOT 
                                          #THE SECOND. It will only run whichever
                                          #flag I put in first.

我试图使上面的最后一行^工作,以便它同时输出d和f(-df)。在GetOpts中有什么方法可以做到这一点吗?

GetOpts支持接受多个语句,但是它不会接受带有强制语句的多个语句。正如我们在上文中看到的,以下情况不起作用:

./testfind.sh -df /home | wc -l
当我们查看提供给getopts的所有标志选项时,我们会看到以下内容

getopts :f:d: opt
注意:这就是我犯错误的地方。f和d标志都希望在末尾有一个强制语句。由于getopts不支持这一点,因此它不是将f作为第二个标志来读取,而是将其作为强制语句本身来读取。为了绕过这一点,我做了以下工作:

#!/bin/bash

while getopts :fd opt  #NOTE: ONLY USE SHORT FLAGS! THIS WAY, GET OPTS
do                     #CAN EASILY CALL ON WHATEVER YOU THROW AT IT.
                       #MULTIPLE MANDATORY ARGUMENTS NOT SUPPORTED BY GETOPTS.
case $opt in
f)                        
    fOption=$OPTARG    #The variable ${2} is where all the power in this
    find ${2} -type f  #Script lies. By default, getOpts is taking every
    ;;                 #Argument you throw at it after the name of the
                       #Script. In this case It's everything after
d)                     #./testfind.sh . For Example, it took -df and set
    dOption=$OPTARG    #-df to $1. The same way, it takes /home and set
    find ${2} -type d  #/home itself to $2. 
    ;;
esac
done
shift $((OPTIND -1))
所需的一切都在注释中解释(在#的右侧)。这个相同的概念现在适用于任何目录和您抛出的标志。只要标志有效且目录有效,它就会找到您需要的任何内容,并按您想要的任何顺序打印出来。您甚至可以抛出./testfind-dfdfdf/home,它将打印您提供给它的目录中的每个标志。尼托:是


-马克·普洛特尼克(Mark Plotnick)的评论强调了getopts是如何读取带有强制语句的标志的。谢谢

我不确定你能不能把这些短标志“链”在一起,因为它们都需要单独的参数。在布尔/开关类标志中,这种链接似乎更有意义。我还没考过。是的,这次我和你在同一条船上。对于作业,我需要将这两个链接到可以使用-df和-fd的位置。我知道getopts并没有被深入讨论,所以我决定试一试并询问一下。我知道,如果没有强制命令,您可以将它们链接起来。伙计,我在这一点上被难住了。我不知道有任何getopt或getopts允许这样做。事实上,如果将
d
指定为使用getopt接受一个强制参数,
-df
表示“这是d选项,它的参数是f”。也许您可以在脚本中设置一个条件来检查传递的参数是否是脚本中使用的标志,如果是,您可以接受后面的参数并将其分配给两个标志。但不会是一个getopts功能。
#!/bin/bash

while getopts :fd opt  #NOTE: ONLY USE SHORT FLAGS! THIS WAY, GET OPTS
do                     #CAN EASILY CALL ON WHATEVER YOU THROW AT IT.
                       #MULTIPLE MANDATORY ARGUMENTS NOT SUPPORTED BY GETOPTS.
case $opt in
f)                        
    fOption=$OPTARG    #The variable ${2} is where all the power in this
    find ${2} -type f  #Script lies. By default, getOpts is taking every
    ;;                 #Argument you throw at it after the name of the
                       #Script. In this case It's everything after
d)                     #./testfind.sh . For Example, it took -df and set
    dOption=$OPTARG    #-df to $1. The same way, it takes /home and set
    find ${2} -type d  #/home itself to $2. 
    ;;
esac
done
shift $((OPTIND -1))