Bash中的脚本参数

Kri*_*fer 93 linux parameters bash shell

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

ocrscript.sh -from /home/kristoffer/test.png -to /home/kristoffer/test.txt
Run Code Online (Sandbox Code Playgroud)

然后该脚本将图像文件转换为文本文件.这是我到目前为止提出的:

#!/bin/bash
export HOME=/home/kristoffer
/usr/local/bin/abbyyocr9 -rl Swedish -if ???fromvalue??? -of ???tovalue??? 2>&1
Run Code Online (Sandbox Code Playgroud)

但我不知道如何获得-from-to价值观.关于如何做的任何想法?

git*_*rik 112

您提供给bashscript的参数将出现在变量中$1,$2并且$3数字引用参数.$0是命令本身.

参数由空格分隔,所以如果你在命令中提供-from-to,它们也会在这些变量中结束,所以为此:

./ocrscript.sh -from /home/kristoffer/test.png -to /home/kristoffer/test.txt
Run Code Online (Sandbox Code Playgroud)

你会得到:

$0    # ocrscript.sh
$1    # -from
$2    # /home/kristoffer/test.png
$3    # -to
$4    # /home/kristoffer/test.txt
Run Code Online (Sandbox Code Playgroud)

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

ocrscript.sh /home/kristoffer/test.png /home/kristoffer/test.txt
Run Code Online (Sandbox Code Playgroud)

然后你会有:

$1    # /home/kristoffer/test.png
$2    # /home/kristoffer/test.txt
Run Code Online (Sandbox Code Playgroud)

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

然后你可以这样做:

/usr/local/bin/abbyyocr9 -rl Swedish -if "$1" -of "$2" 2>&1
Run Code Online (Sandbox Code Playgroud)

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


Man*_*y D 63

如果你没有完全依赖于使用"from"和"to"作为你的选项名称,那么使用getopts实现它是相当容易的:

while getopts f:t: opts; do
   case ${opts} in
      f) FROM_VAL=${OPTARG} ;;
      t) TO_VAL=${OPTARG} ;;
   esac
done
Run Code Online (Sandbox Code Playgroud)

getopts 是一个处理命令行参数的程序,可以方便地为您解析它们.

f:t:指定您期望2个包含值的参数(由冒号表示).像f:t:v说的-v只会被解释为旗帜.

opts是存储当前参数的位置.该case声明是您处理此事的地方.

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

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

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


Sti*_*anE 33

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


use*_*658 22

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

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;
Run Code Online (Sandbox Code Playgroud)

理由:我也包含了一个launcher.sh脚本,因为整个操作有几个步骤,彼此是准独立的(我说的是"准",因为即使每个脚本都可以单独运行,它们通常都是一起运行的),在两天内我发现,大约一半的同事,程序员和所有人,都太好了,不能使用启动器文件,按照"使用",或阅读每次他们做某事时显示的帮助错了,他们弄乱了整个事情,用错误的顺序运行脚本并抱怨脚本无法正常工作.作为胆怯的我,我决定彻底检查我的所有剧本,以确保他们是同事证明.上面的代码段是第一件事.

  • 我喜欢这个。我在末尾添加了一个部分,否则echo“ Invalid parameter:$ {!i}”((i ++))fi` (2认同)

Jak*_* M. 6

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

/usr/local/bin/abbyyocr9 -rl Swedish -if "$1" -of "$2" 2>&1
Run Code Online (Sandbox Code Playgroud)

所以你可以使用:

./your_script.sh some_source_file.png destination_file.txt
Run Code Online (Sandbox Code Playgroud)

双引号说明;

考虑三个脚本:

# foo.sh
bash bar.sh $1

# cat foo2.sh
bash bar.sh "$1"

# bar.sh
echo "1-$1" "2-$2"
Run Code Online (Sandbox Code Playgroud)

现在调用:

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

$ bash foo2.sh "a b"
1-a b 2-
Run Code Online (Sandbox Code Playgroud)

当你调用foo.sh "a b"它然后调用bar.sh a b(两个参数),并用foo2.sh "a b"它调用bar.sh "a b"(1参数).始终记住参数如何在bash中传递和扩展,它将为您节省很多麻烦.