本问题已经有最佳答案,请猛点这里访问。
所以我的问题是如何在Linux中使用终端命令将文件参数传递给bash脚本?目前我正在尝试用bash编写一个程序,它可以从终端获取一个文件参数,并将其用作程序中的变量。例如我跑步myprogram --file=/path/to/file输入终端。我的程序
#!/bin/bash
File=(the path from the argument)
externalprogram $File (other parameters)
我如何通过我的程序实现这一点?
如果将脚本运行为
myprogram /path/to/file
然后您可以访问脚本中的路径作为$1(对于参数1,类似地,$2是参数2,等等)。
file="$1"
externalprogram"$file" [other parameters]
或者只是
externalprogram"$1" [otherparameters]
如果您想从类似于--file=/path/to/file的东西中提取路径,通常使用getoptsshell函数来完成。但这比引用$1要复杂得多,而且,像--file=这样的开关是可选的。我猜您的脚本需要提供一个文件名,所以在选项中传递它是没有意义的。
注意,所有参数扩展都必须引用,包括$file。
有没有办法实现--file方法?我想这样做是因为如果它在没有--file参数的情况下运行,那么程序可以询问用户应该选择什么文件。它将以这种方式简化程序。
通常只需检查用户是否提供了文件名(参数#包含位置参数的数量),如果没有提供文件或-则使用标准输入。如果要使用--file=语法,请使用case语句。
@菲利普(3条评论):这取决于你想要他们如何解释。但在这种情况下,这可能是有道理的——我只是不小心错过了一个。我会编辑它的。
当文件名中有空格时会发生什么?
@chovy然后bash会在空格中把它分成多个单词。例如,如果文件名为test file.txt,运行externalprogram $file,则外部程序将看到两个参数:"test"和"file.txt",但如果运行externalprogram"$file",则会看到一个参数:"test file.txt"。
我只是想引用一下。
可以使用getopt处理bash脚本中的参数。关于getopt的解释不多。下面是一个例子:
#!/bin/sh
OPTIONS=$(getopt -o hf:gb -l help,file:,foo,bar --"$@")
if [ $? -ne 0 ]; then
echo"getopt error"
exit 1
fi
eval set -- $OPTIONS
while true; do
case"$1" in
-h|--help) HELP=1 ;;
-f|--file) FILE="$2" ; shift ;;
-g|--foo) FOO=1 ;;
-b|--bar) BAR=1 ;;
--) shift ; break ;;
*) echo"unknown option: $1" ; exit 1 ;;
esac
shift
done
if [ $# -ne 0 ]; then
echo"unknown option(s): $@"
exit 1
fi
echo"help: $HELP"
echo"file: $FILE"
echo"foo: $FOO"
echo"bar: $BAR"
参见:
"规范"示例:http://software.frodo.looijaard.name/getopt/docs/getopt-parse.bash
博客帖子:http://www.missiondata.com/blog/system-administration/17/17/
man getopt
…很好的解释
bash支持一个称为"位置参数"的概念。这些位置参数表示在调用bash脚本时在命令行上指定的参数。
位置参数由名称$0、$1、$2引用。等等。$0是脚本本身的名称,$1是脚本的第一个参数,$2是脚本的第二个参数,等等,$*表示除$0以外的所有位置参数(即从$1开始)。
一个例子:
#!/bin/bash
FILE="$1"
externalprogram"$FILE"
必须引用$file。
是的,您是对的,在这种情况下,我们希望$1包含一个文件名,如果文件名包含一个或多个空格,则应引用该文件名以避免分词。但是引用位置参数总是必要的吗?
我认为总是引用所有变量比猜测是否必须引用更容易。位置参数是用户输入的,用户可以输入任何内容,所以除非有文档证明参数进行分词,否则必须对其进行引用。从技术上讲,变量不必在=后和[[...]]内引用,但同样地,引用变量比记住不执行分词的位置更容易。
@菲利普:好的观点。谢谢!
假设您按照david zaslavsky的建议进行操作,那么第一个参数就是要运行的程序(不需要进行选项解析),您将处理如何将参数2传递给外部程序的问题。这是一个方便的方法:
#!/bin/bash
ext_program="$1"
shift
"$ext_program""$@"
shift将删除第一个参数,重命名其余的参数($2变为$1, and so on).$@`引用参数,作为一个单词数组(必须引用!).
如果你必须有你的--file语法(例如,如果有一个默认程序要运行,那么用户不必提供语法),只需用你需要做的$1的任何解析来替换ext_program="$1",也许使用getopt或getopt s。
如果你想自己动手,对于一个特定的案例,你可以这样做:
if ["$#" -gt 0 -a"${1:0:6}" =="--file" ]; then
ext_program="${1:7}"
else
ext_program="default program"
fi
+1用于报价。但是无论是getopt还是getopts都不能解析GNU风格的参数。
@菲利普:getopts不能,但getopt肯定可以,在我的系统上。这可能是因为C函数getopt既有GNU版本,也有非GNU版本。