Я узнал, что эта команда:
echo -e "\a"
вызывает звуковой сигнал на локальной системе, тогда как эта команда:
echo -e "\a" >/dev/console
вызывает звуковой сигнал на удаленной системе.
Почему это? Что >/dev/console
делает эта часть?
Почему выполнение echo -e "\a"
на удаленной машине вызывает локальный звуковой сигнал, а не удаленный?
Почему команда «echo» не любит sudo?
Есть ли схема типа OSI-Layer? Пожалуйста, предоставьте мне какую-нибудь внешнюю документацию.
У меня есть только базовые знания о перенаправлении stdout/stderr в файл, не более того, но вопрос, скорее всего, относится к тому, как спроектировано "Gnu/Linux/Kernel", чтобы требовать перенаправления в
" > /dev/console" для срабатывания удаленного звукового сигнала.
echo "Hello World"
Требуется ли перенаправление удаленного управления на /dev/console?
решение1
echo
записывает свой вывод в свой stdout. Это его файловый дескриптор 1.
В echo -e '\a'
зависимости от echo
реализации это приведет либо к записи символа BEL (значение байта 0x7 в ASCII), за которым следует LF (он же символ новой строки), либо -e \a
за которым следует LF, либо -e
за которыми следуют BEL и LF.
Чтобы написать только символ BEL, вам лучше написать printf '\a'
.
В любом случае, это не имеет большого значения для сути вопроса. printf
, например echo
, запишет то, что ему нужно записать, в свой стандартный вывод.
Если вы введете эту команду в приглашении интерактивной оболочки без перенаправления, stdout будет унаследован от оболочки. Если оболочка была запущена эмулятором терминала, например, xterm
или screen
, дескриптор файла 1 будет открыт (с помощью xterm
) на /dev/pt<something>
файле устройства (см. lsof -ad1 -p "$$"
или readlink -f /proc/self/fd/1
в Linux). Это будет подчиненная сторона псевдотерминальной пары.
Единственное, что важно знать об этом, это то, что это своего рода канал связи. Немного похоже на трубу, за исключением того, что у него есть несколько дополнительных наворотов, которые помогают взаимодействовать с пользователем.
Итак, когда printf
записывает BEL в этот файл устройства, происходит то, что он передается на что-то на другом конце. В данном xterm
случае это сам эмулятор терминала. Символ BEL является управляющим символом, который заставляет терминал и эмуляторы терминала оповещать пользователя каким-либо образом ( \a
для оповещения). Это может быть звуковой сигнал, звонок или визуальное мигание экрана или и то, и другое. xterm
обычно использует XBell()
для этого вызов API X11 или мигает своим окном, если он был настроен на использование визуального звонка. screen
сам просто пересылает BEL нахозяинтерминал(ы), к которым он подключен, и где это окно экрана активно, или выдать терминалвспышкауправляющая последовательность или сообщение «Wuff, Wuff!!» (так в оригинале) в зависимости от того, как оно было настроено (см. info screen vbell
).
Если вы входите в систему на ПК с Linux вне графического сеанса, fd 1 будет открыт (пользователем getty
) для /dev/tty<1-...>
устройства. Здесь ядро реализует эмулятор терминала и использует монитор для вывода и клавиатуру(ы) для ввода. Тот же принцип, когда printf
пишет, что BEL там, ядро заставляет динамик ПК издать звуковой сигнал.
Когда вы запускаете эту команду в приглашении интерактивной оболочки через ssh
, fd 1 также будет псевдотерминальным устройством ( /dev/pt<something>
), на этот раз запущенным сервером ssh, который запустил оболочку входа удаленного пользователя на удаленной системе. На другом конце пары псевдотерминалов находится сервер ssh. При получении этого BEL (или чего-либо еще, если это имеет значение), сервер ssh отправляет его через зашифрованное соединение клиенту ssh, а клиент ssh записывает его в свой stdout, который в конечном итоге попадет в окно терминала, за которым вы сидите.
В
printf '\a' > /dev/console
Перед запуском оболочка открывает /dev/console
файл в файловом дескрипторе 1 (stdout) printf
.
Теперь /dev/console
, по крайней мере в Linux, это файл устройства tty, который предназначен для получения системных сообщений. /dev/console
обычно перенаправляет на другое устройство tty. На ПК по умолчанию это тот, /dev/tty0
который указывает на текущий активный виртуальный терминал, но это можно изменить во время загрузки с помощью console=/dev/anything
параметра ядра (например, console=/dev/ttyS0
сделать его первым последовательным устройством), и его даже можно изменить (для части вывода) позже, с помощью TIOCCONS
ioctl()
(см xterm -C
. ).
В любом случае, это будет терминал, который обычно подключен к самой машине. Поэтому вывод BEL там предназначен для оповещения администратора этой машины, поскольку она использует канал, используемый для отправки системных сообщений пользователю.
Чтобы написать сообщение всем вошедшим в систему пользователям, вы также можете использовать приложение wall
или write
приложение только для одного пользователя (одного терминального устройства), при условии, что эти пользователи не отключили эти уведомления (с помощью mesg n
).