如何在 Linux 中使用终端命令将文件参数传递给我的 bash 脚本? [复制]

Posted

技术标签:

【中文标题】如何在 Linux 中使用终端命令将文件参数传递给我的 bash 脚本? [复制]【英文标题】:How can I pass a file argument to my bash script using a Terminal command in Linux? [duplicate] 【发布时间】:2011-04-01 20:20:36 【问题描述】:

所以我的问题是如何在 Linux 中使用终端命令将文件参数传递给我的 bash 脚本? 目前我正在尝试用 bash 制作一个程序,该程序可以从终端获取文件参数并将其用作程序中的变量。例如我跑 myprogram --file=/path/to/file 在终端中。

我的程序

#!/bin/bash    
File=(the path from the argument)  
externalprogram $File (other parameters)

如何通过我的程序实现这一点?

【问题讨论】:

【参考方案1】:

您可以使用 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

链接失效。这里来自互联网档案:

https://web.archive.org/web/20100325015445/http://software.frodo.looijaard.name/getopt/docs/getopt-parse.bash

https://web.archive.org/web/20130827004301/http://www.missiondata.com/blog/system-administration/17/17/

【讨论】:

【参考方案2】:

如果你只是运行你的脚本会更容易(而且更“正确”,见下文)

myprogram /path/to/file

然后您可以以$1 的形式访问脚本中的路径(对于参数#1,类似地$2 是参数#2,等等)

file="$1"
externalprogram "$file" [other parameters]

或者只是

externalprogram "$1" [otherparameters]

如果你想从--file=/path/to/file 之类的东西中提取路径,通常使用getopts shell 函数来完成。但这比仅仅引用$1 更复杂,此外,像--file= 这样的开关是可选的。我猜你的脚本需要提供一个文件名,所以在选项中传递它是没有意义的

【讨论】:

请注意,所有参数扩展都必须引用,包括$file 有没有办法实现 --file 方法?我想这样做是因为如果它在没有 --file 参数的情况下运行,程序可能会询问用户应该选择哪个文件。它将以这种方式简化程序。 通常只检查用户是否提供了文件名(参数# 包含位置参数的数量),如果没有给出文件或-,则使用标准输入。如果您想要--file= 语法,请使用case 语句。 @Philipp(3 cmets up):这取决于您希望如何解释它们。但在这种情况下,这可能是有道理的——我只是不小心错过了一个。我会编辑它。 文件名中有空格怎么办?【参考方案3】:

假设您按照 David Zaslavsky 的建议进行操作,因此第一个参数只是 要运行的程序(不需要选项解析),您正在处理如何传递参数 2 的问题并转到您的外部程序。这里有一个方便的方法:

#!/bin/bash
ext_program="$1"
shift
"$ext_program" "$@"

shift 将删除第一个参数,重命名其余参数($2 变为 $1, and so on).$@` 指的是参数,作为一个单词数组(它必须被引用!)。

如果你必须有你的--file 语法(例如,如果有一个默认程序要运行,那么用户不必提供一个),只需将ext_program="$1" 替换为你对$1 的任何解析需要做的,也许使用 getopt 或 getopts。

如果您想自己动手,仅针对一种特定情况,您可以执行以下操作:

if [ "$#" -gt 0 -a "$1:0:6" == "--file" ]; then
    ext_program="$1:7"
else
    ext_program="default program"
fi

【讨论】:

+1 用于引用。但是getoptgetopts 都不能解析 GNU 风格的参数。 @Philipp:getopts 不能,但 getopt 绝对可以,无论如何在我的系统上。这大概是因为有 GNU 和非 GNU 版本的 C 函数 getopt【参考方案4】:

Bash 支持称为“位置参数”的概念。这些位置参数表示调用 Bash 脚本时在命令行上指定的参数。

位置参数由名称$0$1$2...等引用。 $0 是脚本本身的名称,$1 是脚本的第一个参数,$2 第二个等等。$* 代表所有位置参数,除了$0(即以@ 开头) 987654329@)。

一个例子:

#!/bin/bash
FILE="$1"
externalprogram "$FILE" <other-parameters>

【讨论】:

是的,你是对的,在这种情况下,我们希望$1 包含一个文件名,如果文件名包含一个或多个空格,则应该引用它以避免分词。但是引用位置参数总是有必要吗? 我认为总是引用所有变量比猜测它们是否必须被引用更容易。位置参数是用户输入,用户可以输入任何内容,因此除非记录了参数经历了分词,否则必须引用它。从技术上讲,变量不必在= 之后和[[...]] 内引用,但引用它们比记住不执行分词的位置更容易。 @Philipp:好点。谢谢!

以上是关于如何在 Linux 中使用终端命令将文件参数传递给我的 bash 脚本? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何将命令行参数传递给 unix/linux 系统上正在运行的进程?

如何将命令行参数传递给 PowerShell ps1 文件

如何将命令行参数传递给 WinForms 应用程序?

如何将额外的额外参数传递给批处理文件?

如何将命令行参数传递给 Node.js 程序?

如何将命令行参数传递给 Node.js 程序?