使用bash中的输入重定向运算符读取命令行参数

时间:2016-08-01 20:29:16

标签: bash shell scripting

我需要阅读命令行参数。第一个arg是脚本名称。第二个是重定向运算符,即“<”第三个是输入文件名。当我尝试使用“$#”时,我得到0.当我使用“$ *”时,它什么都没给我。我必须使用“<”这个运营商。我的输入文件包含所有用户输入数据。如果我不使用运算符,它会询问用户输入。有人可以帮帮我吗?谢谢!

命令行:

./script_name < input_file

脚本:

 echo "$*"       # gave nothing
 echo "$#"       # gave me 0

我需要读取输入文件名并将其存储到某个变量中。然后我必须改变它的扩展。任何帮助/建议应该表示赞赏。

3 个答案:

答案 0 :(得分:2)

<用于输入重定向。而<右侧的任何内容都不是命令行参数。

因此,当你执行./script_name < input_file时,会有零(0)个命令行参数传递给脚本,因此$#将为零。

对于你的作品,你需要将你的剧本称为:

./script_name input_file

在您的脚本中,您可以使用以下内容更改扩展程序:

mv -- "$1" "${1}_new_extension"

编辑:这不是OP想要做的。

Altough,已经有了另一个答案,我会写这个是为了完整。如果您 使用&#39;&lt;&#39;重定向你可以在你的脚本中做这样的事情。

while read filename; do
mv -- "$filename" "${filename}_bak"
done 

并将脚本调用为./script < input_file。但请注意,在这种情况下,您无法从stdin获取输入。

答案 1 :(得分:2)

当用户运行时:

./script_name <input_file

...... 完全相当于如果他们执行以下操作:

(exec <input_file; exec ./script_name)

...首先从input_file重定向stdin,然后调用名为./script_name 的脚本,不带任何参数

您可以使用特定于操作系统的接口来获取与句柄相关联的文件名(当它有一个句柄时),但是使用其中一个会使您的脚本只能在提供该接口的操作系统上运行;它不值得。

# very, very linux-specific, won't work for "cat foo | ./yourscript", generally evil
if filename=$(readlink /proc/self/fd/0) && [[ -e $filename ]]; then
  set -- "$@" "$filename" # append filename to the end of the argument list
fi

如果你想避免在给出一个参数时提示输入,并拥有该参数的文件名,那么就不要把它作为参数,而是作为参数,并且做在脚本:

中自己重定向
#!/bin/bash

if [[ $1 ]]; then
  exec <"$1" # this redirects your stdin to come from the file
fi

# ...put other logic here...

...并让用户调用您的脚本:

./script_name input_file

正如./yourscript <filename在标准输入上运行yourscript filename的内容一样,调用./yourscript filename的{​​{1}}调用的脚本将包含内容执行该命令后,在其stdin上exec <"$1"

答案 2 :(得分:0)

不幸的是,如果您希望将重定向运算符作为脚本的参数,那么如果不将命令行参数用引号括起来,您将无法做到这一点:

./script_name "<input_file"

这样做的原因是 shell(至少是 bash 或 zsh)在调用您的脚本之前处理命令。当 shell 解释您的命令时,它会显示:

[shell command (./script_name)][shell input redirection (<input_file)]

使用引号有效地调用脚本会导致:

[shell command (./script_name)][script argument ("<input_file")]

抱歉,这晚了几年;希望有人会觉得这很有用。