我的台式机配置为 30 分钟不活动后进入睡眠状态。我正在使用 Samba 将硬盘上的电影共享到家庭网络。问题是,尽管我正在家庭网络上流式传输电影,但它会在 30 分钟后挂起。显然,Samba 共享未注册为活动。我怎样才能让它看到 Samba 共享正在进行中并推迟挂起?操作系统是 Linux Mint。
答案1
咖啡因是包管理器中提供的实用程序,其功能与脚本类似。它会定期注入无意义的键盘活动,这样系统就不会显得空闲。Caffeine 会在系统托盘中放置一个图标,您可以打开或关闭该图标,这很方便。发布者的描述提到它在全屏模式下工作。我上次使用它时,我认为它不需要全屏模式。但最坏的情况是,让应用程序在该工作区全屏显示。
答案2
我做到了!我会解释如何做,也许这会对其他人有所帮助。
安装 xdotool
sudo apt install xdotool
然后,在/usr/local/bin/中创建一个脚本
sudo xed /usr/local/bin/checksmb.sh
将其复制到 xed:
#!/bin/bash
export DISPLAY=:0
export XAUTHORITY=/home/sinisab89/.Xauthority
if [ `sudo smbstatus | grep DENY | wc -l` != 0 ]
then
xdotool key F9
exit 0
fi
保存存档。
DISPLAY 和 XAUTHORITY 是 CRON 正常运行所必需的。smbstatus 只能通过 sudo 运行。我选择了 F9 键,也许有更好的选择。脚本读取 smbstatus,如果报告中的“DENY”条目超过 0 个(Samba 中的活动连接),则模拟按下 F9 键,这将重置系统空闲计时器并防止挂起。如果有 0 个“DENY”条目,则脚本不执行任何操作。
使checksmb.sh可执行
sudo chmod +x /usr/local/bin/checksmb.sh
现在设置 CRON 每 x 分钟执行一次脚本。我选择了 20 分钟。
sudo crontab -e
滚动到底部并添加
*/20 * * * * /usr/local/bin/checksmb.sh >> /home/YOUR USERNAME/cron.log 2>&1
/home/YOUR USERNAME/cron.log 2>&1 在您的主文件夹中创建一个 cron.log 文件。如果脚本无法正确执行,您可以使用它来进行故障排除。
使用此命令,您可以查看 CRON 是否在给定时间执行脚本
less /var/log/syslog | grep checksmb
这不是最优雅的解决方案,但它确实有效。如果有人知道,例如,视频播放器如何防止系统休眠,那么最好修改此脚本,使其不使用 xdotool。一定有一些系统暂停抑制剂,但我在网上找不到任何东西。
我认为 Caffeine 需要用户输入,不会自动运行。抱歉,我是这样回复的,但它不允许我发表评论……
答案3
我使用此脚本解决了这个问题,该脚本由 Cron 运行,时间间隔接近电源管理的挂起设置。
$ crontab -e
*/10 * * * * $HOME/.local/bin/suppress-suspension.sh
脚本内容:
#! /usr/bin/env bash
export DISPLAY=:0
export XAUTHORITY=$HOME/.Xauthority
ALLOW_IDLE=250000
if [ "$(xprintidle)" -gt $ALLOW_IDLE ]; then
if [ "$(sudo smbstatus | grep --count DENY)" -gt 0 ] ||
[ "$(pgrep --count rclone)" -gt 0 ]; then
eval "$(xdotool getmouselocation --shell)"
xdotool mousemove "$X" "$Y"
exit 0
fi
fi
ALLOW_IDLE
- IDLE 阈值(以毫秒为单位),超过该阈值后将执行后续脚本逻辑,该值必须小于您的屏幕/暂停超时(在我的示例中为 4 分 10 秒)。
xprintidle
- 微小的命令行工具以毫秒为单位返回用户的空闲时间。
sudo smbstatus | grep --count DENY
- 只需过滤掉命令DENY
输出中的行smbstatus
,然后使用--count
选项。
如果 IDLE 超时已超过阈值,并且检测到任何被 smb 服务器阻止的路径,我们只需获取当前鼠标指针坐标并通过调用 eval 将它们存储在环境变量中:
eval "$(xdotool getmouselocation --shell)"
最后,在退出之前,让假老鼠移动到相同的位置:
xdotool mousemove "$X" "$Y"
此事件将当前 IDLE 超时重置为 0,从而防止系统挂起/屏幕关闭。
如您所见,我还通过检查克隆进程正在运行以与云存储同步,我也不想中断它:
pgrep --count rclone
以同样的方式,您可以控制任何应阻止系统挂起的进程,只需添加更多条件:
...
[ "$(pgrep --count rclone)" -gt 0 ] ||
[ "$(pgrep --count foo)" -gt 0 ] ||
[ "$(pgrep --count bar)" -gt 0 ]; then
...
所有指定的进程完成后,所有条件都不会返回真,系统将根据您的电源管理设置暂停。
答案4
(因为所有其他答案都是黑客行为、过于专业化或仅限于特定/过时的桌面软件......)
这是一个非常简单的单行代码,它以通用方式完成这项工作,将网络交互视为键盘交互。因此,您环境的不活动超时设置仍然可以使用。
shopt -s extglob; sum="$( cat /sys/class/net/!(lo|vir*)/statistics/*_bytes | awk '{s+=$1} END {print s}' )"; if [[ "$sum" -gt "$(cat /tmp/network-activity.last_bytes)" ]]; then echo "$sum" > /tmp/network-activity.last_bytes; kbd="$(ls /dev/input/by-path/*-kbd | head -n 1)"; evemu-event "$kbd" --type EV_KEY --code KEY_SLEEP --value 1 --sync; evemu-event "$kbd" --type EV_KEY --code KEY_SLEEP --value 0 --sync; fi
或者,以人类可读的形式:
shopt -s extglob # To be able to filter loopback and virtual NICs.
sum="$( cat /sys/class/net/!(lo|vir*)/statistics/*_bytes | awk '{s+=$1} END {print s}' )" # Total transferred bytes
if [[ "$sum" -gt "$(cat /tmp/network-activity.last_bytes)" ]]; then # Was something transferred since the last time?
echo "$sum" > /tmp/network-activity.last_bytes # Remember
kbd="$(ls /dev/input/by-path/*-kbd | head -n 1)" # find first keyboard
evemu-event "$kbd" --type EV_KEY --code KEY_WAKEUP --value 1 --sync # Press WAKEUP key
evemu-event "$kbd" --type EV_KEY --code KEY_WAKEUP --value 0 --sync # Release again
fi
将其放入您的 crontab 中或从 crontab 运行的脚本中,每分钟执行一次,就好了。
它所需要的只是和evemu-tools
。(将它翻译成另一个 shell 应该很容易。并且仅用于对所有网络字节求和。) 确保它以 的身份运行,以便能够访问事件设备文件。很好,因为它完全与软件无关。它实际上只是发送输入事件,就好像它们来自硬件一样。方便的是,它使用 键,该键在正常系统上永远不应该触发或在软件中映射,但请确保它没有映射到某些东西,或者更改它。awk
bash
awk
root
evemu-tools
WAKEUP