【问题标题】:bash stdout redirection in a for loopfor循环中的bash stdout重定向
【发布时间】:2020-01-30 21:03:50
【问题描述】:

可能重复

你好,

我正在为 bash for 循环中的输出重定向而苦苦挣扎。我有几个类似的 bash 脚本,每个脚本都在不同的输入文件上启动。脚本调用了一个带有一些参数的工具。

bash 脚本是这样的:

my_tool --input input_file --arg1 arg1_name --arg2 arg2_name > output_dir/result_X.dat

X 是每个脚本唯一的字符串。

我在 for 循环中运行所有这些:

for script in scripts_dir/*.sh
do
    bash $script
done

但是,每次运行的标准输出仍然显示在终端上。指定的输出文件已创建,但为空。我该如何解决?我在 stackoverflow 上发现了其他问题,答案是在一个大输出文件中重定向整个循环,但我想避免这种情况。

如果我将 > output_dir/result_X.dat 替换为 > /dev/null :标准输出显示在终端上

如果我将 > output_dir/result_X.dat 替换为 ` 2> /dev/null :什么都不会显示。

提前致谢。

【问题讨论】:

  • 您确定程序没有写入标准错误
  • 什么是an_identifier_defined_in_the_script.dat? shell 会在脚本执行之前解析该行,因此如果您尝试在脚本中定义输出文件的名称,这将不起作用。
  • @WilliamPursell 它只是一个 ID 字符串。该脚本包含另一个工具的命令行,每次运行时字符串都会更改(但每次运行都有不同的 bash 文件,因此 ID 字符串已经写入)
  • @Amessihel 我只尝试了一个文件:终端上没有显示任何内容,但输出文件仍然是空的:/
  • 是的,这是因为您的程序输出到标准错误!我想我们以前说过这个? 2>&1says 将标准错误重定向到标准输出。你同样可以把2>output/result_X.dat

标签: bash loops stdout


【解决方案1】:

当您启动 my_tool 时,该工具中通常有 3 个文件描述符可用:

  • 标准输入
  • 标准输出
  • STDERR

STDIN 用于输入,因此与此问题无关。 STDOUT 用于标准输出。这是文件描述符 1。如果你这样做

ls 1> /dev/null

ls 的 STDOUT 被写入/dev/null。如果不添加1,如ls > /dev/null,则假定您的意思是STDOUT。

STDERR 被用作最广泛意义上的错误消息的标准输出。 STDERR 的数量为 2。

使用ls 代替my_commandls > file 会将列表放入filels /non_existing_dir_ > file 将把ls 的STDOUT 放在file 中。但是在 STDOUT 上没有输出,因为 STDERR 没有被重定向,所以它会被发送到终端。

所以,总结一下,

ls . /non_existing_dir 2>stderr >stdout

.的目录列表放入stdout文件中,stderr中不存在目录的错误。

使用2>&1,您可以将 filedescriptor2 (STDERR) 的输出重定向到文件描述符 1 (SDTOUT)。

为了使事情复杂一点,您可以添加其他文件描述符编号。例如:

exec 3>file

会将文件描述符 3(新创建的)的输出放在 file 中。还有

ls 1>&3

然后会将文件描述符 1 的输出重定向到文件描述符 3,从而有效地将 ls 的输出放入 file

【讨论】:

  • 我已经知道其中的一部分,但我不知道这个程序正在将输出发送到 stderr !傻我。
猜你喜欢
  • 2019-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-02
  • 2011-08-09
相关资源
最近更新 更多