Bash :Eval & Tee :как получить вывод, захваченный вывод и проверку ошибок

С помощью ipptoolможно настроить задание на двустороннюю печать, добавив

ATTR keyword sides two-sided-long-edge

или

ATTR keyword sides two-sided-short-edge

к описанию работы, в зависимости от желаемого макета.

Подробности см. в RFC 2911 .

0
17.08.2020, 15:00
2 ответа

Вот портативное решение, которое должно работать с большинством, если не со всеми синтаксическими оболочками Bourne; протестировано с bash, dash, ksh93, ksh88, ash, (Борном)shиzsh:

for command in "ls -ßnonsense" "ls -ld /tmp"; do
    foo=`{ eval "$command"; echo $? > /tmp/ps.$$; } | tee /dev/tty;`
    st=`cat /tmp/ps.$$;rm /tmp/ps.$$`
    echo "foo=$foo status=$st"
done
1
18.03.2021, 23:12

Используйте zshвместо:

shell_code='ls' # or ls -ßnonsense...
{ foo=$(eval " $shell_code" >&1 >&3 3>&-); } 3>&1
print -r status=$? output=$foo

Здесь,мы дублируем исходный stdout (, который был бы управляющим tty только в том случае, если бы этот скрипт запускался ненаправленно с терминала )на fd 3, и перенаправлял вывод evalкак на подстановку команд, так и на этот fd 3. (использование собственного teeмеханизма zsh, когда fd перенаправляется более одного раза для вывода ).

С bashи другими оболочками, поддерживающими pipefail(, но не ksh93, если в Linux/Cygwin )в системах с /dev/fd/<n>, вы можете сделать что-то подобное с:

shell_code='ls' # or ls -ßnonsense...
{
  foo=$(
    set -o pipefail
    eval " $shell_code" 3>&- | 
      tee 4>&1 >&3 3>&- /dev/fd/4
  )
} 3>&1

printf 'status=%s output=%s\n' "$?" "$foo"

Если pipefailвключено, статус завершения конвейера соответствует состоянию крайней правой команды в конвейере, которая завершилась ошибкой. Так что здесь будет так же, как eval, если только teeне потерпит неудачу.

Чтобы безоговорочно получить статус выхода eval, с помощью bashвы можете выполнить:

shell_code='ls' # or ls -ßnonsense...
{
  foo=$(
    eval " $shell_code" 3>&- |
      tee 4>&1 >&3 3>&- /dev/fd/4
    exit "$PIPESTATUS"
  )
} 3>&1

printf 'status=%s output=%s\n' "$?" "$foo"

В этих подходах stdout teeявляется исходным stdout, в то время как конвейер подстановки команд подается через /dev/fd/4. Мы делаем это, а не наоборот(tee's stdout для канала подстановки команд, записывая исходный stdout через некоторый/dev/fd/<n>)хотя это немного усложняет код, чтобы обойти тот факт, что последний не будет работать в системах Linux или Cygwin, где открытие /dev/fd/<n>— это не то же самое, что дублирование fd <n>(, но выполнение этого для fd, указывающего на конец записи канала, например, для этой подстановки команд (not ksh93, который вместо этого использует пары сокетов ), функционально эквивалентен)

2
18.03.2021, 23:12

Теги

Похожие вопросы