![Bash 脚本根据桌面环境存在问题。如何解决这个问题?](https://linux22.com/image/91491/Bash%20%E8%84%9A%E6%9C%AC%E6%A0%B9%E6%8D%AE%E6%A1%8C%E9%9D%A2%E7%8E%AF%E5%A2%83%E5%AD%98%E5%9C%A8%E9%97%AE%E9%A2%98%E3%80%82%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E8%BF%99%E4%B8%AA%E9%97%AE%E9%A2%98%EF%BC%9F.png)
系统:Ubuntu 16.04.1 Xenial Xerus
你好,
我用于控制 GPU 风扇速度的 bash 脚本遇到了一个奇怪的问题。
如果 GPU 达到另一个温度范围,此脚本会更改 GPU 风扇速度。
代码:
#!/bin/bash
interval=5
while true; do
current_temp=`nvidia-settings -query GPUCoreTemp| grep gpu | perl -ne 'print $1 if /GPUCoreTemp.*?: (\d+)./;'`
if (("$current_temp" < 45)); then
nvidia-settings -a [gpu:0]/GPUFanControlState=1 -a [fan:0]/GPUTargetFanSpeed=40
elif (("$current_temp" > 45)) && (("$current_temp" < 60)); then
nvidia-settings -a [gpu:0]/GPUFanControlState=1 -a [fan:0]/GPUTargetFanSpeed=50
elif (("$current_temp" > 60)) && (("$current_temp" < 65)); then
nvidia-settings -a [gpu:0]/GPUFanControlState=1 -a [fan:0]/GPUTargetFanSpeed=60
elif (("$current_temp" > 65)) && (("$current_temp" < 70)); then
nvidia-settings -a [gpu:0]/GPUFanControlState=1 -a [fan:0]/GPUTargetFanSpeed=70
elif (("$current_temp" > 70)) && (("$current_temp" < 75)); then
nvidia-settings -a [gpu:0]/GPUFanControlState=1 -a [fan:0]/GPUTargetFanSpeed=80
elif (("$current_temp" > 75)); then
nvidia-settings -a [gpu:0]/GPUFanControlState=1 -a [fan:0]/GPUTargetFanSpeed=100
fi
sleep "$interval"
done
在 Unity DE、Gnome 和 KDE 中,此脚本可以完美地使用,但如果我在 XFCE4 中调用相同的命令(用于调试),./nvautofan.sh
此脚本会出现错误:bash -x ./nvautofan.sh
Gnome 调试输出(预期):
+ interval=5
+ true
++ perl -ne 'print $1 if /GPUCoreTemp.*?: (\d+)./;'
++ grep gpu
++ nvidia-settings -query GPUCoreTemp
+ current_temp=37 # Proper output
+ (( 37 < 45 ))
+ nvidia-settings -a '[gpu:0]/GPUFanControlState=1' -a '[fan:0]/GPUTargetFanSpeed=40'
Attribute 'GPUFanControlState' (LINUX-RIG:0[gpu:0]) assigned value 1.
Attribute 'GPUTargetFanSpeed' (LINUX-RIG:0[fan:0]) assigned value 40.
+ sleep 5
# ...
nvidia-settings -query GPUCoreTemp
输出(侏儒)
Attribute 'GPUCoreTemp' (LINUX-RIG:0.0): 39.
'GPUCoreTemp' is an integer attribute.
'GPUCoreTemp' is a read-only attribute.
'GPUCoreTemp' can use the following target types: X Screen, GPU.
Attribute 'GPUCoreTemp' (LINUX-RIG:0[gpu:0]): 39.
'GPUCoreTemp' is an integer attribute.
'GPUCoreTemp' is a read-only attribute.
'GPUCoreTemp' can use the following target types: X Screen, GPU.
XFCE4 调试输出(无功能)
+ interval=5
+ true
++ nvidia-settings -query GPUCoreTemp
++ grep gpu
++ perl -ne 'print $1 if /GPUCoreTemp.*?: (\d+)./;'
+ current_temp= # An error appeared here
+ (( < 45 ))
nvautofan.sh: line 15: ((: < 45: syntax error: operand expected (error token is "< 45")
+ (( > 45 ))
nvautofan.sh: line 17: ((: > 45: syntax error: operand expected (error token is "> 45")
+ (( > 60 ))
nvautofan.sh: line 19: ((: > 60: syntax error: operand expected (error token is "> 60")
+ (( > 65 ))
nvautofan.sh: line 21: ((: > 65: syntax error: operand expected (error token is "> 65")
+ (( > 70 ))
nvautofan.sh: line 23: ((: > 70: syntax error: operand expected (error token is "> 70")
+ (( > 75 ))
nvautofan.sh: line 25: ((: > 75: syntax error: operand expected (error token is "> 75")
+ sleep 5
# ...
nvidia-settings -query GPUCoreTemp
输出(XFCE)
Attribute 'GPUCoreTemp' (LINUX-RIG:0.0): 38.
'GPUCoreTemp' is an integer attribute.
'GPUCoreTemp' is a read-only attribute.
'GPUCoreTemp' can use the following target types: X Screen, GPU.
因此,面对这个问题,我尝试使用 来解决这个问题sh ./nvautofan.sh
,但我发现了一个在我的脚本文件夹中创建文件的错误(脚本继续不起作用):
+ interval=5
+ true
+ nvidia-settings -query GPUCoreTemp
+ grep gpu
+ perl -ne print $1 if /GPUCoreTemp.*?: (\d+)./;
+ current_temp=
nvautofan.sh: 15: nvautofan.sh: cannot open 45: No such file
+
nvautofan.sh: 15: nvautofan.sh: : Permission denied
+
nvautofan.sh: 17: nvautofan.sh: : Permission denied
+
nvautofan.sh: 19: nvautofan.sh: : Permission denied
+
nvautofan.sh: 21: nvautofan.sh: : Permission denied
+
nvautofan.sh: 23: nvautofan.sh: : Permission denied
+
nvautofan.sh: 25: nvautofan.sh: : Permission denied
+ sleep 5
# ...
如何解决这个问题以便在 XFCE 中正确执行该脚本?
谢谢。
答案1
问题是(无论出于何种原因)XFCE 下的输出nvidia-settings -query GPUCoreTemp
不包含字符串gpu
。它仅显示与 GNOME 下运行的同一命令的输出相比的第一组行。这意味着current_temp
将为空并且稍后的算术扩展将失败。
运行下面的脚本sh
不会解决这个问题。
以下bash
脚本将选择输出第一行末尾的数字并将其用作当前温度(编辑:修改为在注释后使用另一个命令)。
#!/bin/bash
function set_fan_speed {
local speed="$1"
nvidia-settings -a "[gpu:0]/GPUFanControlState=1" \
-a "[fan:0]/GPUTargetFanSpeed=$speed"
}
interval=5
while true; do
current_temp="$( nvidia-smi -a |
grep -F 'GPU Current Temp' | awk '{ print $(NF-1) }' )"
if [[ -z "$current_temp" ]]; then
echo "Something isn't right, current_temp is empty" >&2
exit 1
fi
if (( current_temp < 45 )); then set_fan_speed 40
elif (( current_temp < 60 )); then set_fan_speed 50
elif (( current_temp < 65 )); then set_fan_speed 60
elif (( current_temp < 70 )); then set_fan_speed 70
elif (( current_temp < 75 )); then set_fan_speed 80
else set_fan_speed 100
fi
sleep "$interval"
done
为了便于阅读,我将长命令放入函数中,并删除了不必要的算术测试。我还插入了健全性检查current_temp
。
如果不需要修改,该脚本的未来改进可能包括根本不影响风扇速度。跟踪当前的风扇速度并且在set_fan_speed
不需要时不更新它是显而易见的方法。
注意:我实际上不知道函数nvidia-settings
中的调用是否set_fan_speed
作品。很可能[gpu:0]/
应该将其删除,或者需要进行一些其他修改才能使脚本在 GNOME 和 XFCE 下运行。我的解决方案至少解决了解析温度的主要问题。