Вы должны установить git-it, прежде чем сможете использовать его в качестве команды. git-он не устанавливается, когда вы устанавливаете Github для окон. Используйте это для установки git-it
npm install -g git-it
и попробуйте.
Промывка для stdout
определяется его буферизацией. Буферизация может быть настроена на три режима: _IOFBF
(полная буферизация: ждет, когда возможно fflush()
), _IOLBF
(буферизация строк: триггеры новой строки запускают автоматический сброс) и _IONBF
(всегда используется прямая запись). «Поддержка этих характеристик определяется реализацией и может быть затронута функциями setbuf()
и setvbuf()
». [C99: 7.19.3.3]
«При запуске программы три текстовых потока предварительно заданы и их явно не нужно открывать - стандартный ввод (для чтения обычного ввода), стандартный вывод (для записи обычного вывода) и стандартная ошибка (для записи диагностического вывода). Как первоначально было открыто, стандартный поток ошибок не полностью буферизирован, стандартные входные и стандартные выходные потоки полностью буферизованы тогда и только тогда, когда можно определить поток, чтобы не ссылаться на интерактивное устройство ». [C99: 7.19.3.7]
Итак, происходит то, что реализация делает что-то специфичное для платформы, чтобы решить, будет ли stdout
буферизация. В большинстве реализаций libc этот тест выполняется при первом использовании потока.
printf()
автоматически сбрасывается. fflush()
, если вы не напишите gobloads of данные к нему. printf()
, stdout получил режим буферизации строк. Когда мы поменяем файл fd на файл, он по-прежнему буферизируется, поэтому данные автоматически сбрасываются. Каждый libc имеет широту в как он интерпретирует эти требования, поскольку C99 не указывает, что такое «интерактивное устройство», а также запись stdio в POSIX расширяется (за исключением того, что stderr будет открыт для чтения).
stat()
для проверки, является ли fd tty, и соответственно настройте режим буферизации. (Это вызвано из fileops.c.) stdout
изначально имеет нулевой буфер и выделяется при первом использовании потока на основе характеристик fd 1. Неправильно сочетаются буферизованные и небуферизованные функции ввода-вывода. Такая комбинация должна выполняться очень тщательно, особенно когда код должен быть переносимым. (и плохо писать неуправляемый код ...) Конечно, лучше избегать объединения буферизованного и небуферизованного ввода-вывода в один и тот же файловый дескриптор.
Буферизованный IO: fprintf()
, fopen()
, fclose()
, freopen()
...
Небуферизованный IO: write()
, open()
, close()
, dup()
...
Когда вы используете dup2()
для перенаправление stdout. Функция не знает буфер, который был заполнен fprintf()
. Поэтому, когда dup2()
закрывает старый дескриптор 1, он не очищает буфер и содержимое может быть сброшено на другой выход. В вашем случае 2a оно было отправлено на /dev/null
.
В вашем случае лучше использовать freopen()
вместо dup2()
. Это решает все ваши проблемы:
FILE
. (случай 2a) Вот правильная реализация вашей функции:
void RedirectStdout2File(const char* log_path) {
if(freopen(log_path, "a+", stdout) == NULL) err(EXIT_FAILURE, NULL);
}
К сожалению, с буферизованным IO вы не можете напрямую устанавливать разрешения для вновь созданного файла. Вы должны использовать другие вызовы для изменения разрешений или использовать неперехваченные расширения glibc. См. fopen() man page
.
Вы не должны закрывать дескриптор файла, поэтому удалите close(fd)
и закройте
stdout_bak_fd
, если вы хотите, чтобы сообщение печаталось только в файле.