Терминал или консоль являются частью аппаратных средств, с помощью то, который пользователь может взаимодействовать с хостом. В основном клавиатура вместе с текстовым экраном.
В наше время почти все терминалы и консоли представляют "виртуальные".
Файл, который представляет терминал, традиционно, называют tty файлом. Если Вы посмотрите в соответствии с "/dev" каталогом системы UNIX, то Вы найдете много tty файлов подключенным к виртуальным консолям (например, tty1 на Linux), виртуальные терминалы (например, pts/0) или физически подключенные аппаратные средства (например, ttyS0 является физическим последовательным терминалом, если таковые имеются, присоединенный на первом последовательном порте хоста).
Консоль должна быть частью аппаратных средств, физически подключенных с (или часть) хост. Это имеет специальную роль в системе: это - основной момент для доступа к системе для обслуживания, и некоторая специальная операция может быть сделана только от консоли (например, видеть single user mode
). Терминал может быть и обычно, удаленная часть аппаратных средств.
Наконец, но не наименьшее, оболочка является специальной программой, которая взаимодействует с пользователем посредством управления tty и предложений, пользователю, способ запустить другие программы (например, удар, csh, tcsh).
Эмулятор терминала является программой, которая эмулирует физический терминал (например, xterm, терминал гнома, minicom).
Таким образом, когда Вы обращаетесь к "текстовому окну", в Вашей системе Linux (под X11) Вы обращаетесь: эмулятор терминала, подключенный к виртуальному терминалу, определенному tty файлом, внутри который выполняет оболочку.
Можно использовать unbuffer
команда (который стал частью expect
пакет), например.
unbuffer long_running_command | print_progress
unbuffer
подключения к long_running_command
через псевдотерминал (имущество), которое заставляет систему рассматривать его как интерактивный процесс, поэтому не используя буферизацию 4 кибибитов в конвейере, который является вероятной причиной задержки.
Для более длинных конвейеров Вам, вероятно, придется освободить буфер каждая команда (кроме заключительной), например.
unbuffer x | unbuffer -p y | z
Другой способ освежевать эту кошку состоит в том, чтобы использовать stdbuf
программа, которая является частью Coreutils GNU (FreeBSD также имеет свой собственный).
stdbuf -i0 -o0 -e0 command
Это выключает буферизацию полностью для входа, вывода и ошибки. Для некоторых приложений буферизация строки может более подойти по причинам производительности:
stdbuf -oL -eL command
Обратите внимание, что это только работает на stdio
буферизация (printf()
, fputs()
...) для динамично связанных приложений, и только если то приложение иначе не корректирует буферизацию своих стандартных потоков отдельно, хотя это должно покрыть большинство приложений.
sudo stdbuff … command
работы, хотя stdbuff … sudo command
не сделал. спасибо
– natevw
10.07.2013, 09:05
stdbuf
не работает с tee
, потому что tee
перезаписывает значения по умолчанию, установленные stdbuf
. См. страницу руководства stdbuf
.
– ceving
30.06.2014, 14:51
stdbuf
использование LD_PRELOAD
механизм для вставки его собственной динамично загруженной библиотеки libstdbuf.so
. Это означает, что не будет работать с этими исполняемыми файлами видов: с setuid или набором возможностей файла, статически связанным, не использующий стандарт libc. В этих случаях лучше использовать решения с unbuffer
/ script
/ socat
. См. также stdbuf с setuid/capabilities.
– pabouk
12.10.2015, 12:20
Если это - проблема с libc изменение его буферизации / сбрасывание, когда произведенный не переходит к терминалу, необходимо попробовать socat. Можно создать двунаправленный поток почти между любым видом механизма ввода-вывода. Один из тех является разветвленной программой, говорящей с псевдо tty.
socat EXEC:long_running_command,pty,ctty STDIO
То, что это делает,
Если это дает Вам тот же вывод как long_running_command
, затем можно продолжить канал.
Редактирование: Ничего себе, не видел освобождать буфер ответ! Ну, socat является большим инструментом так или иначе, таким образом, я мог бы просто оставить этот ответ
socat -u exec:long_running_command,pty,end-close -
здесь
– Stéphane Chazelas
07.08.2015, 16:10
Это раньше имело место и вероятно все еще имеет место, что, когда стандартный вывод записан в терминал, это - строка, буферизованная по умолчанию - когда новая строка записана, строка записана в терминал. Когда стандартный вывод отправляется в канал, он полностью буферизуется - таким образом, данные только отправляются в следующий процесс в конвейере, когда стандартный буфер ввода-вывода заполнен.
Это - источник проблемы. Я не уверен, существует ли очень, можно сделать для фиксации его, не изменяя программу, пишущую в канал. Вы могли использовать setvbuf()
функция с _IOLBF
отметьте для безусловного помещения stdout
в строку буферизовал режим. Но я не вижу простой способ осуществить это на программе. Или программа может сделать fflush()
в соответствующих точках (после каждой строки вывода), но тот же комментарий применяется.
Я предполагаю, что при замене канала псевдотерминалом, затем стандартная библиотека I/O думала бы, что вывод был терминалом (потому что это - тип терминала), и выровнял бы буфер автоматически. Это - сложный способ иметь дело с вещами, все же.
Я не думаю, что проблема с каналом. Это кажется, что Ваш длительный процесс не сбрасывает свой собственный буфер достаточно часто. Изменение размера буфера канала было бы взломом для обхода его, но я не думаю его возможное, не восстанавливая ядро - что-то, что Вы не хотели бы делать как взлом, поскольку это, вероятно, неохотно влияет на большое количество других процессов.
Для grep
, sed
и awk
можно вынудить вывод быть буферизованной строкой. Можно использовать:
grep --line-buffered
Вывод силы, чтобы быть буферизованной строкой. По умолчанию вывод является строкой, буферизованной, когда стандартный вывод является терминалом и блоком, буферизованным иначе.
sed -u
Сделайте выходную строку буферизованной.
Посмотрите эту страницу для получения дополнительной информации: http://www.perkin.org.uk/posts/how-to-fix-stdio-buffering.html
Еще один способ включить буферизующий строку режим вывода для long_running_command
должен использовать script
управляйте что выполнения Ваш long_running_command
в псевдотерминале (имущество).
script -q /dev/null long_running_command | print_progress # FreeBSD, Mac OS X
script -c "long_running_command" /dev/null | print_progress # Linux
script
такая старая команда, это должно быть доступно на всех подобных Unix платформах.
– Aaron Digulla
20.01.2013, 15:01
-q
на Linux: script -q -c 'long_running_command' /dev/null | print_progress
– jfs
11.04.2013, 15:51
stdin
, который лишает возможности выполнять такой long_running_command
в фоновом режиме, по крайней мере, при запуске с интерактивного терминала. К обходному решению я смог перенаправить stdin от /dev/null
, начиная с моего long_running_command
не использует stdin
.
– haridsv
15.11.2013, 14:44
Вы можете использовать
long_running_command 1>&2 |& print_progress
Проблема в том, что libc будет буферизовать строку при выводе из стандартного потока на экран и в полном буфере при выводе из файла в файл. Но без буфера для stderr.
Я не думаю, что проблема с буфером конвейера, все дело в политике буферов libc.
Я знаю, что это старый вопрос, на который уже было много ответов, но если вы хотите избежать проблемы с буфером, просто попробуйте что-нибудь вроде:
stdbuf -oL tail -f /var/log/messages | tee -a /home/your_user_here/logs.txt
Это будет выводить журналы в реальном времени, а также сохранять их в файл logs.txt
, и буфер больше не влияет на команду tail -f
.
Я нашел это умное решение: (echo -e "cmd 1 \ ncmd 2" && cat) | ./shell_executable
Это трюк. cat
будет читать дополнительный ввод (до EOF) и передавать его конвейеру после того, как echo
поместит свои аргументы во входной поток shell_executable
.
Подобно ответу chad , вы можете написать небольшой скрипт вроде этого:
# save as ~/bin/scriptee, or so
script -q /dev/null sh -c 'exec cat > /dev/null'
Затем используйте эту команду scriptee
вместо tee
].
my-long-running-command | scriptee
Увы, похоже, я не могу заставить такую версию идеально работать в Linux, поэтому, похоже, ограничивается unix-системами в стиле BSD.
В Linux это близко, но вы не получите обратно приглашение, когда оно закончится (пока вы не нажмете Enter и т. Д.) ...
script -q -c 'cat > /proc/self/fd/1' /dev/null
expect_unbuffer
и находится вexpect-dev
пакет, неexpect
пакет – bdonlan 24.01.2011, 13:14expect-dev
предоставляет обоимunbuffer
иexpect_unbuffer
(первый - символьная ссылка на последнего). Ссылки доступны с тех порexpect 5.44.1.14-1
(2009). – jfs 11.04.2013, 16:00unbuffer
в основномexpect
пакет на debian теперь (это - все еще символьная ссылка наexpect_unbuffer
, который является также в основномexpect
пакет) – cas 05.11.2015, 01:50