2010-08-10 5 views
4

Все, что я действительно хочу сделать, это убедиться, что все в конвейере успешно выполнено и назначить последний stdin переменной. Рассмотрим следующий упрощенных вниз сценарий:Использование xargs для назначения stdin переменной

x=`exit 1|cat`

Когда я бегу declare -a, я вижу это:

declare -a PIPESTATUS='([0]="0")'

мне нужен какой-то способ, чтобы заметить exit 1, поэтому я преобразовал его к этому:

exit 1|cat|xargs -I {} x={}

И declare -a дал мне:

declare -a PIPESTATUS='([0]="1" [1]="0" [2]="0")'

Это то, что я хотел, так что я пытался увидеть, что произойдет, если exit 1 не произошло:

echo 1|cat|xargs -I {} x={}

Но он терпит неудачу с :

xargs: x={}: No such file or directory

Есть ли способ присвоить xargs {} - x? Как насчет других методов работы PIPESTATUS и назначения stdin переменной?

Примечание: эти примеры заглушены. Я не делаю exit 1, echo 1 или cat, но использовал эти команды для упрощения, поэтому мы можем сосредоточиться на моей конкретной проблеме.

ответ

1

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

Возможно, вы сможете что-то сделать с именованными трубами (mkfifo) или возможной функцией bash's read?

EDIT:

Может быть, просто перенаправить вывод в файл, то вы можете использовать PIPESTATUS:

command1 | command2 | command3 >/tmp/tmpfile 
## Examine PIPESTATUS 
X=$(cat /tmp/tmpfile) 
+0

Я думал, что чтение может сделать что-то подобное. echo 1 | read x не работает. У вас есть пример? – User1

3

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

Когда вы используете xargs, он ничего не знает о оболочке, поэтому он не может назначать переменные.

Просьба set -o pipefail, тогда вы можете получить статус от $?.

+0

pipefail - хороший вариант для рассмотрения. Тем не менее, мне жаль, что я не смог бы получить PIPESTATUS для всего, что было в трубопроводе. – User1

0

Как насчет ...

read x <<<"$(echo 1)" 
read x < <(echo 1) 

echo "$x" 
+0

Интересные мысли. Использование (exit 1 | cat) по-прежнему не заполняет PIPESTATUS. – User1

0

Почему не просто заполнить новый массив?

IFS=$'\n' read -r -d '' -a result < <(echo a | cat | cat; echo "PIPESTATUS='${PIPESTATUS[*]}'") 
IFS=$'\n' read -r -d '' -a result < <(echo a | exit 1 | cat; echo "PIPESTATUS='${PIPESTATUS[*]}'") 

echo "${#result[@]}" 
echo "${result[@]}" 
echo "${result[0]}" 
echo "${result[1]}" 
Смежные вопросы