Linux Bash 中的脚本参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18003370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 00:26:40  来源:igfitidea点击:

Script parameters in Bash

linuxbashshellparameters

提问by Kristoffer

I'm trying to make a shell script which should be used like this:

我正在尝试制作一个应该像这样使用的shell脚本:

ocrscript.sh -from /home/kristoffer/test.png -to /home/kristoffer/test.txt

The script will then ocr convert the image file to a text file. Here is what I have come up with so far:

然后脚本将 ocr 将图像文件转换为文本文件。这是我到目前为止的想法:

#!/bin/bash
export HOME=/home/kristoffer
/usr/local/bin/abbyyocr9 -rl Swedish -if ???fromvalue??? -of ???tovalue??? 2>&1

But I don't know how to get the -fromand -tovalues. Any ideas on how to do it?

但我不知道如何获得-from-to值。关于如何做到这一点的任何想法?

采纳答案by gitaarik

The arguments that you provide to a bashscript will appear in the variables $1and $2and $3where the number refers to the argument. $0is the command itself.

您提供给 bashscript 的参数将出现在变量中$1$2并且$3数字是指参数的位置。$0是命令本身。

The arguments are seperated by spaces, so if you would provide the -fromand -toin the command, they will end up in these variables too, so for this:

参数用空格分隔,所以如果你在命令中提供-fromand -to,它们也会在这些变量中结束,所以对于这个:

./ocrscript.sh -from /home/kristoffer/test.png -to /home/kristoffer/test.txt

You'll get:

你会得到:

ocrscript.sh /home/kristoffer/test.png /home/kristoffer/test.txt
# ocrscript.sh # -from # /home/kristoffer/test.png # -to # /home/kristoffer/test.txt

It might be easier to omit the -fromand the -to, like:

省略-from和可能更容易-to,例如:

    # /home/kristoffer/test.png
    # /home/kristoffer/test.txt

Then you'll have:

那么你将拥有:

/usr/local/bin/abbyyocr9 -rl Swedish -if "" -of "" 2>&1

The downside is that you'll have to supply it in the right order. There are libraries that can make it easier to parse named arguments on the command line, but usually for simple shell scripts you should just use the easy way, if it's no problem.

缺点是您必须以正确的顺序提供它。有一些库可以更轻松地解析命令行上的命名参数,但通常对于简单的 shell 脚本,如果没有问题,您应该只使用简单的方法。

Then you can do:

然后你可以这样做:

/usr/local/bin/abbyyocr9 -rl Swedish -if "" -of "" 2>&1

The double quotes around the $1and the $2are not always necessary but are adviced, because some strings won't work if you don't put them between double quotes.

$1和周围的双引号$2并不总是必需的,但建议使用,因为如果不将它们放在双引号之间,某些字符串将不起作用。

回答by Jakub M.

In bash $1is the first argument passed to the script, $2second and so on

在 bash 中$1是传递给脚本的第一个参数,$2第二个等等

./your_script.sh some_source_file.png destination_file.txt

So you can use:

所以你可以使用:

# foo.sh
bash bar.sh 

# cat foo2.sh
bash bar.sh ""

# bar.sh
echo "1-" "2-"

Explanation on double quotes;

双引号说明;

consider three scripts:

考虑三个脚本:

$ bash foo.sh "a b"
1-a 2-b

$ bash foo2.sh "a b"
1-a b 2-

Now invoke:

现在调用:

while getopts f:t: opts; do
   case ${opts} in
      f) FROM_VAL=${OPTARG} ;;
      t) TO_VAL=${OPTARG} ;;
   esac
done

When you invoke foo.sh "a b"then it invokes bar.sh a b(two arguments), and with foo2.sh "a b"it invokes bar.sh "a b"(1 argument). Always have in mind how parameters are passed and expaned in bash, it will save you a lot of headache.

当您调用时,foo.sh "a b"它会调用bar.sh a b(两个参数),并随之foo2.sh "a b"调用bar.sh "a b"(1 个参数)。始终牢记在 bash 中参数是如何传递和扩展的,它会为您省去很多麻烦。

回答by StianE

Use the variables "$1", "$2", "$3"and so on to access arguments. To access all of them you can use "$@", or to get the count of arguments $#(might be useful to check for too few or too many arguments).

使用变量"$1""$2""$3"等来访问参数。要访问所有这些,您可以使用"$@",或获取参数的数量$#(检查太少或太多的参数可能很有用)。

回答by Manny D

If you're not completely attached to using "from" and "to" as your option names, it's fairly easy to implement this using getopts:

如果您不完全喜欢使用“from”和“to”作为您的选项名称,那么使用getopts实现这一点相当容易:

for ((i=1;i<=$#;i++)); 
do

    if [ ${!i} = "-s" ] 
    then ((i++)) 
        var1=${!i};

    elif [ ${!i} = "-log" ];
    then ((i++)) 
        logFile=${!i};  

    elif [ ${!i} = "-x" ];
    then ((i++)) 
        var2=${!i};    

    elif [ ${!i} = "-p" ]; 
    then ((i++)) 
        var3=${!i};

    elif [ ${!i} = "-b" ];
    then ((i++)) 
        var4=${!i};

    elif [ ${!i} = "-l" ];
    then ((i++)) 
        var5=${!i}; 

    elif [ ${!i} = "-a" ];
    then ((i++)) 
        var6=${!i};
    fi

done;

getoptsis a program that processes command line arguments and conveniently parses them for you.

getopts是一个处理命令行参数并方便地为您解析它们的程序。

f:t:specifies that you're expecting 2 parameters that contain values (indicated by the colon). Something like f:t:vsays that -vwill only be interpreted as a flag.

f:t:指定您需要 2 个包含值的参数(用冒号表示)。像这样f:t:v-v只会被解释为一个标志。

optsis where the current parameter is stored. The casestatement is where you will process this.

opts是当前参数的存储位置。该case声明是在那里你会处理这一点。

${OPTARG}contains the value following the parameter. ${FROM_VAL}for example will get the value /home/kristoffer/test.pngif you ran your script like:

${OPTARG}包含参数后面的值。${FROM_VAL}例如,/home/kristoffer/test.png如果您运行脚本,将获得该值:

ocrscript.sh -f /home/kristoffer/test.png -t /home/kristoffer/test.txt

ocrscript.sh -f /home/kristoffer/test.png -t /home/kristoffer/test.txt

As the others are suggesting, if this is your first time writing bash scripts you should really read up on some basics. This was just a quick tutorial on how getoptsworks.

正如其他人所建议的,如果这是您第一次编写 bash 脚本,您应该真正阅读一些基础知识。这只是一个关于如何getopts工作的快速教程。

回答by user1628658

I needed to make sure that my scripts are entirely portable between various machines, shells and even cygwin versions. Further, my colleagues who were the ones I had to write the scripts for, are programmers, so I ended up using this:

我需要确保我的脚本在各种机器、shell 甚至 cygwin 版本之间完全可移植。此外,我不得不为其编写脚本的同事是程序员,所以我最终使用了这个:

##代码##

Rationale: I included a launcher.shscript as well, since the whole operation had several steps which were quasi independent on each other (I'm saying "quasi", because even though each script could be run on its own, they were usually all run together), and in two days I found out, that about half of my colleagues, being programmers and all, were too good to be using the launcher file, follow the "usage", or read the HELP which was displayed every time they did something wrong and they were making a mess of the whole thing, running scripts with arguments in the wrong order and complaining that the scripts didn't work properly. Being the choleric I am I decided to overhaul all my scripts to make sure that they are colleague-proof. The code segment above was the first thing.

基本原理:我也包含了一个launcher.sh脚本,因为整个操作有几个步骤彼此准独立(我说“准”,因为即使每个脚本都可以单独运行,但它们通常都一起运行),两天后我发现,我的大约一半的同事,包括程序员在内,都太好了,无法使用启动器文件、遵循“用法”或阅读每次他们做某事时显示的帮助错了,他们把整个事情弄得一团糟,以错误的顺序运行带有参数的脚本,并抱怨脚本无法正常工作。作为一个胆小鬼,我决定彻底修改我的所有脚本,以确保它们是同事证明的。上面的代码段是第一件事。