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
Script parameters in Bash
提问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 -from
and -to
values. Any ideas on how to do it?
但我不知道如何获得-from
和-to
值。关于如何做到这一点的任何想法?
采纳答案by gitaarik
The arguments that you provide to a bashscript will appear in the variables $1
and $2
and $3
where the number refers to the argument. $0
is the command itself.
您提供给 bashscript 的参数将出现在变量中$1
,$2
并且$3
数字是指参数的位置。$0
是命令本身。
The arguments are seperated by spaces, so if you would provide the -from
and -to
in the command, they will end up in these variables too, so for this:
参数用空格分隔,所以如果你在命令中提供-from
and -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 -from
and 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 $1
and the $2
are 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 $1
is the first argument passed to the script, $2
second 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;
getopts
is 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:v
says that -v
will only be interpreted as a flag.
f:t:
指定您需要 2 个包含值的参数(用冒号表示)。像这样f:t:v
说-v
只会被解释为一个标志。
opts
is where the current parameter is stored. The case
statement 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.png
if 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 getopts
works.
正如其他人所建议的,如果这是您第一次编写 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.sh
script 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
脚本,因为整个操作有几个步骤彼此准独立(我说“准”,因为即使每个脚本都可以单独运行,但它们通常都一起运行),两天后我发现,我的大约一半的同事,包括程序员在内,都太好了,无法使用启动器文件、遵循“用法”或阅读每次他们做某事时显示的帮助错了,他们把整个事情弄得一团糟,以错误的顺序运行带有参数的脚本,并抱怨脚本无法正常工作。作为一个胆小鬼,我决定彻底修改我的所有脚本,以确保它们是同事证明的。上面的代码段是第一件事。