我正在使用bash。我有一个文件F包含Java程序的命令行参数,我需要存储Java程序的两个输出,即标准输出和退出值的输出。存储标准输出通过
工作cat F | xargs java program > Output
但是xargs不允许访问Java程序的退出代码。 好吧,我拆分它,运行程序两次,一次用于标准输出,一次用于退出代码---但是获取退出代码并正确运行它似乎是不可能的。有人可能会尝试
java program $(cat F)
但是如果F包含例如“”,那么这不起作用,即程序的一个命令行参数是空格。问题是参数$(cat F)的扩展。
现在我没有办法解决这个问题?我不想要“$(cat F)”,因为我希望$(cat F)扩展成许多字符串---但我不想进一步扩展这些字符串。
另一方面,如果有一个更好的xargs,可以访问原始退出值,这将解决问题,但我不知道。
答案 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)
我担心这个问题真的不太清楚,所以我会明确地做出这些假设:
文件F
每行有一个参数,除了换行符之外的所有空格都是重要的,并且不需要替换反斜杠转义符,例如\t
。
您只需要使用所有参数调用java程序一次。
您需要保留退出状态。
通过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
传递所有命令行参数。
答案 2 :(得分:0)
如果你有GNU Parallel(并且不介意STDERR上的额外输出):
cat F | parallel -Xj1 --halt 1 java program > Output
echo $?