简体   繁体   English

Bash:使用getopts传递参数

[英]Bash: Passing parameters using getopts

I know this is a simple question and I have been examining the getopts tutorials and examples, but I am stuck. 我知道这是一个简单的问题,我一直在研究getopts教程和示例,但是我很困惑。 If you check this link, you will see that with the help of @fedorqui, I have managed to write the code in order to get an element of an array in a file. 如果您检查链接,您将看到在@fedorqui的帮助下,我设法编写了代码,以获取文件中数组的元素。

However, what I need is to parameterize the inputs so that the script will continue to work even if I change the order of inputs. 但是,我需要对输入进行参数化,以便即使更改输入的顺序脚本也可以继续工作。

This is the first code I wrote: 这是我编写的第一个代码:

#!/bin/bash

file=$3 row=$1 col=$2 str1="Hata: " str2=". satır " str3=". sütun yok"

if [ $row -gt 3 ]
then
    echo $str1$row$str2$col$str3
elif [ $col -gt 3 ]
then
    echo $str1$row$str2$col$str3
else
    awk 'NR==row{print $col}' row=$row col=$col $file
fi 

Now, the script works like $ ./tablooku.sh 3 2 tablom.dat and the output is: 现在,脚本的工作方式类似于$ ./tablooku.sh 3 2 tablom.dat ,输出为:

~/Desktop $ ./tablooku.sh 3 2 tablom.dat 
Kopenhag

What I need to do is to translate this code so that when I enter $ ./tablooku.sh -r 3 -c 2 tablom.dat , I get the script work. 我需要做的就是翻译这段代码,以便在输入$ ./tablooku.sh -r 3 -c 2 tablom.dat ,脚本可以正常工作。

This is the code I wrote which stucks upon running: 这是我编写的在运行时卡住的代码:

#!/bin/bash

str1="Hata: "
str2=". satır "
str3=". sütun yok"

while getopts "r:c:f:" opts
do
            case $opts in
            r)     row=$OPTARG echo "-r was triggered, Parameter: $OPTARG";;
            c)     col=$OPTARG echo "-c was triggered, Parameter: $OPTARG";;
            f)     fi=$OPTARG echo "-f was triggered, Parameter: $OPTARG";;
            \?)     printf "Kullanım: %s -r değer -c değer dosya adresi\n" $0
                          exit 2;;
           esac
done

if [ $row -gt 3 ]
then
    echo $str1$row$str2$col$str3
elif [ $col -gt 3 ]
then
    echo $str1$row$str2$col$str3
else
    awk 'NR==r{print $c}' r=$row c=$col $fi
fi

Can you please tell me what is wrong here? 你能告诉我这里有什么问题吗? When I run the command the system output is: 当我运行命令时,系统输出为:

~/Desktop $ ./go_test.sh -r 3 -c 2 tablom.dat 
-r was triggered, Parameter: 3
-c was triggered, Parameter: 2
./go_test.sh: line 23: [: -gt: unary operator expected
./go_test.sh: line 26: [: -gt: unary operator expected

The prompt stucks and I have to use ctrl+z to break the waiting. 提示卡住了,我必须使用ctrl+z来打破等待状态。 It looks like I am failing to assign the file location to fi but I could not solve the problem 看来我无法将文件位置分配给fi但是我无法解决问题

Note: Please remember -r is row, - c is column and the last parameter is the file location which does not use any option code (such as -f) 注意:请记住-r是行,-c是列,最后一个参数是不使用任何选项代码的文件位置(例如-f)

UPDATE 1: 更新1:

I changed the if brackets ] with ]] and [ with [[ . 如果括号我改变了]]][[[ Now the unary operator expected error is gone. 现在, unary operator expected错误已消失。 Now, the prompt waits and does not print -f was triggered, Parameter:... I still use ctrl+z to break the waiting. 现在,提示等待并且不打印-f was triggered, Parameter:...我仍然使用ctrl+z来打破等待。

UPDATE 2: 更新2:

With the suggestion of both @grebneke and @TimK, I added the semi-colons and changed the fi parameter to fil . 在@grebneke和@TimK的建议下,我添加了分号并将fi参数更改为fil This way, I get the script working. 这样,我就可以运行脚本了。 However, there is one little problem remaining. 但是,仍然存在一个小问题。 The code works if I enter $ ./tablooku.sh -r 3 -c 2 -f tablom.dat . 如果输入$ ./tablooku.sh -r 3 -c 2 -f tablom.dat则该代码有效。 However, I need it to run without having to write -f . 但是,我需要它运行而不必编写-f Is it possible? 可能吗?

In these lines: 在这些行中:

        r)     row=$OPTARG echo "-r was triggered, Parameter: $OPTARG";;
        c)     col=$OPTARG echo "-c was triggered, Parameter: $OPTARG";;
        f)     fi=$OPTARG echo "-f was triggered, Parameter: $OPTARG";;

You are assigning row/col/fi for the remainder of the line only. 您仅为行的其余部分分配row/col/fi行。 Add a semicolon after the assignment and it will stay assigned for the rest of the script: 在分配之后添加分号,它将在其余脚本中保持分配状态:

        r)     row=$OPTARG; echo "-r was triggered, Parameter: $OPTARG";;
        c)     col=$OPTARG; echo "-c was triggered, Parameter: $OPTARG";;
        f)     fi=$OPTARG; echo "-f was triggered, Parameter: $OPTARG";;

Edit <deleted, I misunderstood the question> 编辑 <deleted, I misunderstood the question>

Edit 2 To get the remaining arguments after using getopts , you must shift like this: 编辑2要在使用getopts之后获取其余参数,您必须像这样进行shift

while getopts "r:c:" opts
do
...
done

shift $(( $OPTIND-1 ))

# Now, $1, $2 etc are your arguments as you are used to:
$ ./tablooku.sh -r 3 -c 2 tablom.dat
# $1 will be "tablom.dat"

You're missing a semi-colon in where you're setting $row, $col, and $fi. 您在设置$ row,$ col和$ fi的位置缺少分号。

        case $opts in
        r)     row=$OPTARG echo "-r was triggered, Parameter: $OPTARG";;
        c)     col=$OPTARG echo "-c was triggered, Parameter: $OPTARG";;
        f)     fi=$OPTARG echo "-f was triggered, Parameter: $OPTARG";;
        \?)     printf "Kullanım: %s -r değer -c değer dosya adresi\n" $0
                      exit 2;;
       esac

Should be (semi-colon before the echo ): 应该是( echo之前的分号):

        case $opts in
        r)     row=$OPTARG ; echo "-r was triggered, Parameter: $OPTARG";;
        c)     col=$OPTARG ; echo "-c was triggered, Parameter: $OPTARG";;
        f)     fi=$OPTARG ; echo "-f was triggered, Parameter: $OPTARG";;
        \?)     printf "Kullanım: %s -r değer -c değer dosya adresi\n" $0
                      exit 2;;
       esac

Without those semi-colons, your commands are not being run as you would expect, as you can see looking at the output of bash -x, and examine the lines with -gt: 如果没有这些分号,您的命令将无法按预期运行,因为您可以看到bash -x的输出,并使用-gt检查行:

bash-[576]$ bash -x foo.bash -r 3 -c 3 -f foo
+ str1='Hata: '
+ str2='. satır '
+ str3='. sütun yok'
+ getopts r:c:f: opts
+ case $opts in
+ row=3
+ echo '-r was triggered, Parameter: 3'
-r was triggered, Parameter: 3
+ getopts r:c:f: opts
+ case $opts in
+ col=3
+ echo '-c was triggered, Parameter: 3'
-c was triggered, Parameter: 3
+ getopts r:c:f: opts
+ case $opts in
+ fi=foo
+ echo '-f was triggered, Parameter: foo'
-f was triggered, Parameter: foo
+ getopts r:c:f: opts
+ '[' -gt 3 ']'
foo.bash: line 18: [: -gt: unary operator expected
+ '[' -gt 3 ']'
foo.bash: line 20: [: -gt: unary operator expected
+ awk 'NR==r{print $c}' r= c=

With the semi-colons: 使用分号:

bash-[574]$ bash -x foo.bash -r 3 -c 3 -f foo
+ str1='Hata: '
+ str2='. satır '
+ str3='. sütun yok'
+ getopts r:c:f: opts
+ case $opts in
+ row=3
+ echo '-r was triggered, Parameter: 3'
-r was triggered, Parameter: 3
+ getopts r:c:f: opts
+ case $opts in
+ col=3
+ echo '-c was triggered, Parameter: 3'
-c was triggered, Parameter: 3
+ getopts r:c:f: opts
+ case $opts in
+ fi=foo
+ echo '-f was triggered, Parameter: foo'
-f was triggered, Parameter: foo
+ getopts r:c:f: opts
+ '[' 3 -gt 3 ']'
+ '[' 3 -gt 3 ']'
+ awk 'NR==r{print $c}' r=3 c=3 foo

Again, look at the lines with -gt. 再次,用-gt查看行。 So your variable settings of $row, $col, and $fi are not propagating without the ; 因此,如果没有$,$ col和$ fi的变量设置,则不会传播; .

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

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