2

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

cat F | xargs java program > Output

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

java program $(cat F)

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

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

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

4

3 回答 3

3

这是做你想做的吗?

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///命令时具有“魔法”的字符。

于 2015-01-22T02:30:12.593 回答
0

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

cat F | parallel -Xj1 --halt 1 java program > Output
echo $?
于 2015-02-01T23:56:26.757 回答
0

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

  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.

于 2015-01-22T04:53:47.990 回答