我了解到这个命令:
echo -e "\a"
在本地系统上触发蜂鸣声,而此命令:
echo -e "\a" >/dev/console
在远程系统上触发蜂鸣声。
为什么是这样?该部分在做什么>/dev/console
?
为什么echo -e "\a"
在远程计算机上执行会在本地而不是远程触发蜂鸣声?
为什么“echo”-命令不喜欢 sudo ?
有类似OSI层的方案吗?请向我提供一些外部文档。
我对将 stdout/stderr 重定向到文件只有基本的了解,但问题更可能是指“Gnu/Linux/Kernel”是如何设计的,以便要求重定向到
“ > /dev/console”用于发出远程蜂鸣声。
远程是否echo "Hello World"
需要重定向到 /dev/console ?
答案1
echo
将其输出写入其标准输出。这是它的文件描述符 1。
对于echo -e '\a'
,根据echo
实现的不同,将写入一个 BEL 字符(ASCII 中的 0x7 字节值),后跟 LF(又名换行符),或者-e \a
后跟 LF,或者-e
后跟 BEL 和 LF。
要仅编写 BEL 字符,您宁愿编写printf '\a'
.
无论如何,这对这个问题的核心没有多大影响。printf
,就像echo
将其必须写入其标准输出的内容写入。
如果您在交互式 shell 的提示符下输入该命令而不进行重定向,则 stdout 将从 shell 继承。如果 shell 是由终端仿真器(如xterm
或 )启动的screen
,则文件描述符 1 将在设备文件xterm
上/dev/pt<something>
(请参阅Linux 上的lsof -ad1 -p "$$"
或)打开(由 ) readlink -f /proc/self/fd/1
。这将是伪终端对的从属端。
这里唯一需要了解的是它是某种沟通渠道。有点像管道,只不过它有更多有助于用户交互的花哨功能。
因此,当printf
将 BEL 写入该设备文件时,会发生将其传输到另一端的情况。在这种xterm
情况下,那就是终端模拟器本身。 BEL 字符是一个控制字符,使终端和终端仿真器以某种方式警告用户(\a
用于警告)。这可以是可听见的蜂鸣声、提示音或屏幕的视觉闪烁,或两者兼而有之。xterm
通常会使用XBell()
X11 API 调用,或者如果已配置为使用可视铃声,则闪烁其窗口。screen
它本身会简单地将 BEL 转发给主持人它所连接的终端以及该屏幕窗口处于活动状态或发出终端的位置闪光控制序列或“Wuff,Wuff!!” (原文如此)消息取决于它的配置方式(请参阅info screen vbell
)。
如果您在图形会话之外登录运行 Linux 的 PC,则 fd 1 将已(由getty
)打开到/dev/tty<1-...>
设备。在这里,内核实现了终端仿真器并使用监视器进行输出,使用键盘进行输入。同样的原理,当printf
在那里写入 BEL 时,内核会让 PC 扬声器发出蜂鸣声。
当您在交互式 shell 的提示符下运行该命令时ssh
,fd 1 也将是一个伪终端设备 ( /dev/pt<something>
),这次由 ssh 服务器启动,该服务器在远程系统上启动远程用户的登录 shell。伪终端对的另一端是 ssh 服务器。当收到该 BEL(或任何其他相关内容)时,ssh 服务器会通过加密连接将其发送到 ssh 客户端,然后 ssh 客户端将其写入其标准输出,最终将其发送到您所在的终端窗口在。
在
printf '\a' > /dev/console
shell/dev/console
在运行之前打开文件描述符 1 (stdout) 上的文件printf
。
现在/dev/console
,至少在 Linux 上,是用于接收系统消息的 tty 设备文件。/dev/console
通常重定向到另一个 tty 设备。在 PC 上,默认情况下,它/dev/tty0
指向当前活动的虚拟终端,但可以在启动时使用console=/dev/anything
内核参数更改它(例如console=/dev/ttyS0
使其成为第一个串行设备),甚至可以更改它(对于输出部分)稍后使用TIOCCONS
ioctl()
(参见xterm -C
)。
无论如何,那将是一个通常连接到机器本身的终端。因此,在那里输出 BEL 是为了提醒该机器的管理员,因为它正在使用用于向用户发送系统消息的通道。
要向所有登录的用户写入消息,您还可以使用该wall
应用程序,或write
仅向一个用户(一台终端设备)使用该应用程序,前提是这些用户尚未禁用这些通知(带有mesg n
)