【问题标题】:Either getting original return value from xargs or simulate xargs从 xargs 获取原始返回值或模拟 xargs
【发布时间】:2015-03-20 17:52:54
【问题描述】:

我正在使用 bash。我有一个包含 Java 程序命令行参数的文件 F,我需要存储 Java 程序的 both 输出,即标准输出和退出值的输出。存储标准输出通过

cat F | xargs java program > Output

但是 xargs 不能访问 Java 程序的退出代码。 好吧,我拆分它,运行程序两次,一次用于标准输出,一次用于退出代码 --- 但是获取退出代码并正确运行它似乎是不可能的。大家可以试试

java program $(cat F)

但是如果 F 包含例如“”,即程序的一个命令行参数,它是一个空格,则这不起作用。问题在于参数 $(cat F) 的扩展。

现在我没有办法解决这个问题?我不想要“$(cat F)”,因为我希望 $(cat F) 扩展为许多字符串 --- 但我不希望进一步扩展这些字符串。

另一方面,如果有更好的 xargs,可以访问原始退出值,那将解决问题,但我不知道。

【问题讨论】:

  • 您需要将状态码和输出放在同一个文件中吗?你怎么知道下一个文件的输出从哪里开始?
  • 我只需要将状态码存储在一个变量中(在 bash 脚本中)。
  • 文件F 是什么样的?您如何处理其中包含空格的参数?是每行一个参数,还是..?

标签: bash xargs exit-code variable-expansion


【解决方案1】:

这是你想要的吗?

cat F | xargs bash -c 'java program "$@"; echo "Returned: $?"' - > Output

或者,正如@rici 正确指出的那样,避免使用UUOC

xargs bash -c 'java program "$@"; echo "Returned: $?"' - < F > Output

或者类似的东西(虽然我没有考虑过这样做的所有后果,所以这可能是一个坏主意)。

{ sed -e 's/^/java program /' F | bash -s; echo "Returned $?"; } > Output

这使您可以将返回码存储在xargs 版本不提供的变量中(至少不在xargs-spawned shell 之外。

sed -e 's/^/java program /' F | bash -s > Output; ret=$?

要使用${program} shell 变量,只需直接扩展它即可。

xargs bash -c 'java '"${program}"' "$@"; echo "Returned: $?"' - < F > Output

sed -e 's/^/java '"${program}"' /' F | bash -s > Output; ret=$?

请注意替换s/// 命令中的“魔法”字符。

【讨论】:

  • uuoc。 xargs ... &lt; F &gt; output
  • @rici 不假思索地从 OP 复制。谢谢。
  • 对不起,我花了太长时间才弄清楚细节。原则上它可以工作(谢谢!),两个 xargs 版本,但现在我需要将返回值存储在一个变量中,而不是硬编码的“程序”我需要 ${program};对我来说似乎有点微妙。
  • 我对 sed 解决方案有点担心,所以我只是将返回的值保存到一个文件中。现在问题解决了!
  • @OliverKullmann 我不确定这是否有意义,但可以肯定。我几乎在帖子中建议过,但不认为这是值得的。
【解决方案2】:

恐怕这个问题真的不是很清楚,所以我将这里的假设明确:

  1. 文件F 每行有一个参数,除换行符之外的所有空格都很重要,并且不需要替换反斜杠转义符,例如\t

  2. 您只需调用 java 程序一次,并使用所有参数。

  3. 您需要保留退出状态。

这可以很容易地在bash 中通过将F 读入带有mapfile 的数组中来完成:

# Invoked as: do_the_work program < F > output
do_the_work() {
  local -a args
  mapfile -t args
  java "$@" "${args[@]}"
}

该函数的状态返回正是java可执行文件的状态返回,因此您可以在调用后立即捕获它:

do_the_work my_program
rc=$?

为方便起见,该函数还允许您在命令行上指定参数;它使用"$@" 传递所有命令行参数,然后传递从stdin 读取的参数。

【讨论】:

    【解决方案3】:

    如果您有 GNU Parallel(并且不介意 STDERR 上的额外输出):

    cat F | parallel -Xj1 --halt 1 java program > Output
    echo $?
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-02
      • 2015-09-01
      • 1970-01-01
      • 2017-11-17
      • 1970-01-01
      • 2011-07-08
      • 2019-01-15
      相关资源
      最近更新 更多