Как сохранить stdout в файл, stderr в файл, stdout+stderr в файл и получить stdout + stderr на терминал, как обычно для сценария оболочки

git clean -X -f -n

git clean -Xудалит все файлы, соответствующие шаблонам в .gitignore. -nв конце приводит к тому, что он фактически не удаляет файлы, а только пробный запуск, сообщая о файлах, которые были бы удалены.

Добавьте -d, чтобы также удалить игнорируемые каталоги.

Без -Xудаляет неотслеживаемые файлы (, но не игнорируемые файлы ).

См. git clean --help.

4
15.04.2020, 16:37
3 ответа

Простое расширение вашего подхода:

exec 2> >(tee -a stderr stdall) 1> >(tee -a stdout stdall)

Стандартная ошибка будет записана в файл с именем stderr, стандартный вывод — в stdout, а стандартная ошибка и стандартный вывод также будут записаны в консоль (или на то, на что указывают два дескриптора файла в это время. execзапускается )и в stdall.
tee -a(добавить )требуется для предотвращения перезаписи stdallвторым tee, который начинает запись в него.

Обратите внимание, что порядок, в котором выполняются перенаправления, имеет значение :подстановка второго процесса зависит от первого перенаправления, т. е. выданные им ошибки будут отправлены >(tee -a stderr stdall). Конечно, вы можете перенаправить стандартную ошибку подстановки второго процесса на /dev/null, чтобы избежать этого побочного эффекта. Перенаправление стандартного вывода перед стандартной ошибкой также отправит каждую ошибку в stdoutи stdall.

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

5
19.03.2021, 02:29

I'm creating a CI/CD library and I'm unable to know what the clients would use the library for, so I want to account for each use case.

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

1
19.03.2021, 02:29

Ваш сценарий может выполняться через$0(с установкой и проверкой переменной среды, чтобы избежать бесконечной рекурсии )вместо того, чтобы полагаться на конструкцию bash > >(...), которая IMLE капризна и ненадежна.

if [ "$REDIRECTED" != 1 ]; then
        export REDIRECTED=1
        set -o pipefail
        { { "$0" | tee stdout >&3; } 2>&1 | tee stderr; } 3>&1 | tee stdboth
        exit
fi
# rest of your script here

Поскольку teeне использует буферизацию строк (и не может быть принужден к этому с помощью stdbuf(1)), порядок данных, записываемых в stdout и stderr, не будет соблюдаться в окончательном выводе. С командой, которая использует полную буферизацию и запись как в stdout, так и в stderr, даже строка -buffering teeне поможет, и, что еще хуже, вы можете получить выходные строки, которые наполовину являются stdout и наполовину stderr.

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

2
19.03.2021, 02:29

Теги

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