Относятся ли отчеты о ходе выполнения / информация о журналах к stderr или stdout?

Используйте

cp /path/to/files/*t_1* /path/to/destination

или просто

cp ./*t_1* /path/to/destination

если файлы находятся в текущем каталоге.

Или,

for f in ./*t_1*; do
    cp "$f" /path/to/destination
done

Это должно сработать наверняка, даже если в текущем каталоге много тысяч файлов, соответствующих шаблону.

76
13.04.2017, 15:36
5 ответов

Posix определяет стандартные потоки таким образом :

При запуске программы должны быть предопределены три потока, и их не нужно открывать явно: стандартный ввод (для чтения обычного ввода), стандартный вывод (для записи обычного вывода) и стандартный вывод ошибок (для записи диагностического вывода). При открытии стандартный поток ошибок не полностью буферизуется; потоки стандартного ввода и вывода полностью буферизуются тогда и только тогда, когда можно определить, что поток не относится к интерактивному устройству.

Библиотека GNU C описывает стандартные потоки аналогичным образом:

Переменная: ФАЙЛ * stdout
Стандартный поток вывода, который используется для обычного вывода. из программы.

Переменная: ФАЙЛ * stderr
Стандартный поток ошибок, который используется для сообщений об ошибках и диагностики, выдаваемых программой.

Таким образом, стандартные определения содержат мало указаний по использованию потока, помимо «обычного / нормального вывода» и «вывода диагностики / ошибок». На практике обычно перенаправляют один или оба этих потока в файлы и конвейеры, где индикаторы выполнения будут проблемой.Некоторые системы даже отслеживают вывод stderr и считают это признаком проблем. Таким образом, чисто вспомогательная информация о ходе выполнения проблематична в любом из потоков.

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

Для некоторых очень простых сообщений о ходе выполнения («Запуск X» ... «Готово с X») более разумно включать вывод даже для неинтерактивных потоков. В этом случае подумайте, как пользователи могут взаимодействовать с потоками, например, поиск с помощью grep или поиск по страницам с помощью less или мониторинг с помощью tail -f . Если имеет смысл видеть сообщения о ходе выполнения в этих контекстах, их будет намного легче использовать из stdout .

38
27.01.2020, 19:31

POSIX немного конкретизирует "диагностическую информацию" в Shell and Utilities, 1.4: Utility Description Defaults (выделение мое):

STDERR

Раздел STDERR описывает стандартный вывод ошибок утилиты. Описываются только те сообщения, которые целенаправленно посылаются утилитой. описаны. Использование терминала для стандартной ошибки может привести к тому, что любая из стандартных утилит, которые пишут стандартный вывод ошибок, может остановиться при использовании в фоновом режиме. По этой причине приложения не должны использовать интерактивные функции в сценариях, которые должны быть размещены в фоновом режиме.

Формат диагностических сообщений для большинства утилит не определен, но язык и культурные соглашения диагностических и информационных сообщений, формат которых не определен в данном томе POSIX.1-2008, должны быть затронуты установкой LC_MESSAGES и [XSI] [Option Start] NLSPATH. [Option End]

Указанный стандартный вывод ошибок стандартных утилит не должен зависеть от существования или значения переменных окружения, определенных в данном томе POSIX.1-2008, за исключением случаев, предусмотренных в данном томе POSIX.1-2008. POSIX.1-2008.

Default Behavior: Когда этот раздел указан как "Стандартная ошибка должна использоваться только для диагностических сообщений.", это означает, что, если не указано иное, диагностические сообщения должны посылаться в стандартную ошибку только тогда, когда статус выхода указывает, что произошла ошибка произошла и утилита используется так, как описано в данном томе стандарта POSIX.1-2008.

Когда этот раздел указан как "Не используется.", это означает, что стандартная ошибка не должна использоваться, когда утилита используется так, как описано в данном томе POSIX.1-2008.

IANASL, но я интерпретирую это как то, что stderr будет иметь вывод только в том случае, если утилита вернет код выхода из ошибки. Поскольку это не должно быть нормальным ходом событий для успешного выполнения, никакая информация о ходе выполнения не должна печататься утилитой POSIX, если не произошла ошибка (если, конечно, не указано иное и т.д.).

14
27.01.2020, 19:31

POSIX определяет стандартную ошибку как

для записи диагностического вывода

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

81
27.01.2020, 19:31

Сообщение об использовании должно идти в stdout, если пользователь вызвал его с помощью --help и в stderr, если он допустил ошибку. Безусловная печать в stderr нежелательна, так как затрудняет просмотр сообщения с помощью пейджера/grep/etc.

Также, могу я предложить третий способ: открыть /dev/tty для отчетов о прогрессе/спиннеров/etc.

-1
27.01.2020, 19:31

По принципу исключения может идти только на stderr. Да, я знаю, что вы спрашивали об официальной спецификации, которую я не могу представить вам, кроме ссылки на спецификацию POSIX, данную Стивеном Киттом, в которой говорится, что stderr предназначен для диагностических целей.

Более важным моментом является то, что stdin и stdout имеют функцию, которая запрещает вывод отчетов о ходе выполнения в stdout - они, конечно, формируют последовательность каналов, которая в командах оболочки Unix является не просто побочным эффектом, а самой сутью мощный конвейерный подход.

Итак. Ничего, кроме реальной "полезной нагрузки" вашей программы, не относится к stdout. Если ваша программа не выводит данные, на стандартный вывод ничего не должно поступать. Это оставляет stderr для всего остального , включая отчеты о ходе выполнения.

Конечно, это оставляет дыру - вероятно, было бы неплохо иметь "stdfluff" или что-то подобное, которое не предназначено ни для вывода, ни для ошибок, а для отчетов о ходе выполнения, отладки и чего-то подобного. Фактически, ничто не мешает вам сделать это, т.е. вы можете вывести свой прогресс в файловый дескриптор 3. Пример:

$ perl -e 'open($fd, ">", "/dev/fd/3"); print $fd "hello\n"'

Это не дает никаких результатов. (*)

$ perl -e 'open($fd, ">", "/dev/fd/3"); print $fd "hello\n"'  3>&1
hello

Это печатается на fd-3, который перенаправляется на stdout.

(*) Первый пример не дает вывода, но все еще немного надуман; открыть не удается и $! не будет содержать такого файла или каталога ; просто возьмите это как пример, это, конечно, не должно использоваться как это всерьез.В реальной программе, если вы хотите пойти по этому пути, вы можете проверить, можно ли использовать / dev / fd / 3 , и воспринять это как намек на то, нужно ли активировать отчеты о ходе выполнения; вам придется сделать это довольно рано, чтобы вас не смущали ваши собственные open для реальных файлов и тому подобное ...

13
27.01.2020, 19:31

Теги

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