我已经编写了一个脚本来运行 rsync,并read line
在脚本末尾添加了内容以便在运行后保持输出可见;当我手动运行该脚本时,它可以按预期工作。
我已制定了一条 udev 规则RUN+="/home/user/bin/scriptfile"
来运行上述脚本,并且脚本确实按预期运行,但输出未显示在终端窗口中。为什么不行?我该怎么做?
编辑 - 澄清一下:我尝试从 udev 规则启动各种不同的脚本,并且运行良好,脚本运行并执行我期望的操作。问题是,当脚本运行时,我可以将输出打印到屏幕上吗?我可以将输出定向到日志文件,这也可以,但我希望在脚本运行时将其显示在屏幕上。
答案1
首先,为什么你看不到输出?正如 Sergiy Kolodyazhnyy 在评论中指出的那样,由 udev 启动的脚本“不会继承所有相同的环境变量,这意味着它们无法知道你正在运行哪个 GUI 会话以及在哪里运行。”简而言之,udev 对你的桌面 GUI 一无所知。
我目前对插入系统的 USB 设备执行的操作与您要求的操作类似。对于我正在运行的应用程序,我需要知道 USB 是否具有有效的序列号。无论如何,以下是我实现它的方法。
概述:
- 我启动了一个辅助脚本,创建一个命名管道并监视该命名管道中传输的“消息”。
- 我已将 udev 配置为“发送消息”(写入行)到我的命名管道(在我的情况下是 USB sn 和分区信息)。
- 我的辅助脚本看到每一行文本进来,然后我使用通知发送将消息以通知的形式转储到我的屏幕上。
如果您只是想在终端窗口中看到它,您可以告诉您的帮助脚本在终端窗口中简单地回显来自命名管道的文本。
示例代码:
#!/bin/bash
#This script should be called once without an argument to get it running in a "service" mode
#Successive calls to this script by UDEV sould pass a string as the first argument.
# These strings will then be displayed in the window running in service mode.
pipe=/tmp/messages
if [ "$1" == "" ]; then
[ ! -e "$pipe" ] && mkfifo "$pipe"
while true # this loop continuously reads new lines and echos them
do
line=$(cat "$pipe")
echo "$line"
done
fi
# you won't reach this line unless you call this script with one argument
echo "$1" >> "$pipe"
运行此脚本:
- 将以上内容保存在文件中
/tmp/sample_script.sh
(重启时将被删除) - 使脚本可执行
chmod +x /tmp/sample_script.sh
- 调用脚本使其在服务模式下运行(即不带任何参数)
/tmp/sample_script.sh
- 从另一个终端窗口/脚本/udev 运行
/tmp/sample_script.sh "message to send"
(注意我们在这里传递字符串参数“要发送的消息”) - 回头看一下服务窗口,您会看到窗口中出现了字符串“要发送的消息”。
从 udev 运行脚本时,如果不通过命名管道重定向,您将无法让第二个实例直接在屏幕上输出任何内容,因为您的 udev 脚本是从与您的 GUI 运行的环境完全独立的环境中调用的。在脚本中创建并在两个环境中使用的命名管道充当两者之间的桥梁,允许您将信息从 udev 环境传递到您正在查看的 GUI 环境。