2015-01-22 5 views
2

Я работаю с bash. У меня есть файл F, содержащий аргументы командной строки для Java-программы, и мне нужно сохранить как выходы программ Java, т. Е. Вывод на стандартный вывод и значение выхода. Хранение стандартных выходных работ осуществляется черезЛибо получить исходное возвращаемое значение из xargs, либо имитировать xargs

cat F | xargs java program > Output 

Но xargs не дает доступа к коду выхода программы Java. Итак, я разделил его, дважды запустив программу, один раз для стандартного вывода, один раз для кода выхода, но получение кода выхода и правильное выполнение этого файла кажется невозможным. Можно было бы попробовать

java program $(cat F) 

, но это не будет работать, если F содержит, например, «», а именно: один аргумент командной строки для программы, которая является пространством. Проблема заключается в расширении аргумента $ (cat F).

Теперь я не вижу способа обойти эту проблему? Я не хочу «$ (cat F)», так как я хочу, чтобы $ (cat F) расширялся во многие строки --- но я не хочу дальнейшего расширения этих строк.

Если, с другой стороны, были бы лучшие xargs, дающие доступ к исходному значению выхода, что бы решить проблему, но я не знаю об этом.

+1

вам нужен код состояния и вывод в том же файле делать? Откуда вы знаете, где начинается выход следующего файла? – rici

+0

Код состояния, который мне просто нужно сохранить в переменной (в bash-скрипте). –

+0

Как выглядит файл 'F'? Как вы обрабатываете аргументы с пробелом в них? Это один аргумент в строке или ...? – rici

ответ

2

Это делает то, что вы хотите?

cat F | xargs bash -c 'java program "[email protected]"; echo "Returned: $?"' - > Output 

Или, как @rici правильно указывает, избежать UUOC

xargs bash -c 'java program "[email protected]"; echo "Returned: $?"' - <F> Output 

В качестве альтернативы нечто подобное (хотя я не думал, что через все разветвлений делать это, так что может быть причиной этого это плохая идея).

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

Это позволяет хранить код возврата в переменной в xargs версии не (по крайней мере, не вне xargs -spawned оболочки.

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

Чтобы использовать переменную в ${program} оболочки просто расширить его непосредственно .

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

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

Только остерегайтесь символов, которые «магия» в замене s/// комм а также.

+2

uuoc. 'xargs ... < F > output' – rici

+0

@rici Скопировано из ОП, не задумываясь об этом. Благодарю. –

+0

Извините, мне потребовалось слишком много времени, чтобы выяснить детали. В принципе это работает (спасибо!), Две xargs-версии, но теперь мне нужно сохранить возвращаемое значение в переменной, а вместо жестко запрограммированной «программы» мне нужно $ {program}; кажется немного утонченным для меня. –

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 "[email protected]" "${args[@]}" 
} 

Статус возврата этой функции именно статус возвращение Java исполняемый файл, так что вы могли бы зафиксировать его сразу после разговора:

do_the_work my_program 
rc=$? 

Для удобства функция позволяет также указывать аргументы на командная строка; он использует "[email protected]" для передачи всех аргументов командной строки перед передачей аргументов, считанных с stdin.

0

Если у вас есть GNU Parallel (и не против дополнительного выхода на STDERR):

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