Перенаправление Stderr неожиданно перенаправляет также некоторые встроенные функции BASH

Я пытаюсь скрыть все stderr от пользователей, использующих интерактивный скрипт BASH, но сохраняю ошибки в файле журнала. Однако простое redirect stderr довольно неожиданно скрывает некоторые выходные данные BASH, которые вместо этого должны перейти в stdout . Опробовал это на двух системах и получил одинаковые результаты (одна имеет GNU bash, версия 4.1.2 (1) -релиз (x86_64-redhat-linux-gnu), а другая на MacOS X)

У меня есть длительное подозрение, что это может быть вызвано заменой оболочки exec … но другой встроенный ( times ) работает как положено и выводит на стандартный вывод !

Пример:

 #!/bin/bash exec 2>>file_log echo This will be printed to stdout, as expected ls ThereIsNoSuchFileOnEarth # this will go to “file_log”, as expected read –p 'User would never see this prompt and it would go to file_log. Totally unexpected.' –r -e test species=”Daleks Raxacoricofallapatorians Judoon” select enemy in $species; do # …code omitted as the user would never see the list. It would go into file_log again! done 

    Предполагается, что запросы от read и select переходят к стандартной ошибке, поскольку они предположительно предполагают взаимодействие с пользователем, а не фактический вывод . Это позволяет вам запускать tool.sh > tool.out и по-прежнему использовать read и select для сбора информации от пользователя без «загрязнения» фактического вывода.

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

    По этой же причине curl , например, отображает ход загрузки при стандартной ошибке, а не при стандартном выводе; Вы можете curl http://www.example.com/path/to/file > file и отобразить только содержимое file (и, следовательно, перенаправить в file , в то время как информационные данные отображаются с использованием стандартной ошибки.

    Если вы используете exec для перенаправления stderr для всей оболочки, это влияет на всю оболочку.

    Вы либо не можете использовать exec для перенаправления всего stderr, либо вам нужно вызвать что-то вроде:

     read .... 2> /dev/tty 

    чтобы встроенные данные создавали читаемый вывод для stderr.