要么从xargs获得原始返回值,要么模拟xargs

时间:2015-01-22 02:19:27

标签: bash xargs exit-code variable-expansion

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

工作
cat F | xargs java program > Output

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

java program $(cat F)

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

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

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

3 个答案:

答案 0 :(得分:2)

这样做你想要的吗?

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 - 生成的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///命令时“神奇”的字符。

答案 1 :(得分:0)

我担心这个问题真的不太清楚,所以我会明确地做出这些假设:

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

    < / LI>
  2. 您只需要使用所有参数调用java程序一次。

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

  4. 通过bashF读入包含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传递所有命令行参数。

答案 2 :(得分:0)

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

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