удар: вынудите процесс exec'd освободить буфер stdout

У меня есть сценарий как:

#!/bin/bash
exec /usr/bin/some_binary > /tmp/my.log 2>&1

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

Там какой-либо путь состоит в том, чтобы сделать stdout освободившим буфер, прежде чем я сделаю должностное лицо, которое будет влиять на some_binary, таким образом, он будет иметь более полезный вход?

(Сценарий обертки только устанавливает несколько переменных среды перед должностным лицом, таким образом, решение в жемчуге или Python также было бы выполнимо.)

20
задан Nakilon 9 February 2015 в 08:55
поделиться

3 ответа

Возможно, вам поможет unbuffer скрипт, который поставляется с expect .

13
ответ дан 29 November 2019 в 22:56
поделиться

Некоторые программы командной строки имеют возможность изменять поведение буферизации потока стандартного вывода. Таким образом, если доступен исходный код C ...

# two command options ...
man file | less -p '--no-buffer'
man grep | less -p '--line-buffered'

# ... and their respective source code

# from: http://www.opensource.apple.com/source/file/file-6.2.1/file/src/file.c
if(nobuffer)
   (void) fflush(stdout);

# from: http://www.opensource.apple.com/source/grep/grep-28/grep/src/grep.c
if (line_buffered)
   fflush (stdout);

В качестве альтернативы использованию сценария unbuffer от expect или изменению исходного кода программы вы также можете попробовать использовать сценарий (1), чтобы избежать сбоев стандартного вывода, вызванных ошибкой pipe:

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

# Linux
script -c "[executable string]" /dev/null

# FreeBSD, Mac OS X
script -q /dev/null "[executable string]"
11
ответ дан 29 November 2019 в 22:56
поделиться

GNU coreutils-8.5 также имеет команду stdbuf для изменения буферизации потока ввода/вывода:

http://www.pixelbeat.org/programming/stdio_buffering/

Итак, в вашем примере, просто вызовите:

stdbuf -oL /usr/bin/some_binary > /tmp/my.log 2>&1

Это позволит выводить текст сразу построчно (как только строка завершается символом конца строки "\n" в C). Если вам действительно нужен немедленный вывод, используйте -o0.

Этот способ может быть более желательным, если вы не хотите вводить зависимость от expect через команду unbuffer. Способ unbuffer, с другой стороны, необходим, если вам нужно обмануть some_binary, чтобы он думал, что перед ним настоящий стандартный вывод tty.

28
ответ дан 29 November 2019 в 22:56
поделиться
Другие вопросы по тегам:

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