完美不完美的 Bash 脚本无法将变量传递给 Renice 命令

完美不完美的 Bash 脚本无法将变量传递给 Renice 命令

我编写了一个 bash 脚本,根据 100% 正确https://www.shellcheck.net/#。代码应该重新设定优先级,然后限制任何所需的应用程序及其相关 pid。

#!/bin/bash
INTERVAL=10
PROCESSES_TO_WATCH=gnome-shell
set -x

while sleep $INTERVAL; do
        for process_name in $PROCESSES_TO_WATCH; do
        pid_list=("$(pgrep "$process_name")")

        # Don't do anything if no running process found
        [ ${#pid_list[@]} -le 0 ] && continue

                for pid in "${pid_list[@]}"; do
                renice -n 19 -p "$pid" && cpulimit -p "$pid" -l 20  

                done
        done
done
#EOF

问题:
输出显示 renice 命令正在拒绝“$pid”变量值:

+ sleep 10
+ for process_name in $PROCESSES_TO_WATCH
+ pid_list=("$(pgrep "$process_name")")
++ pgrep gnome-shell
+ '[' 1 -le 0 ']'
+ for pid in "${pid_list[@]}"
+ renice -n 19 -p '1797
3709
3074206'
renice: bad process ID value: 1797
3709
3074206

进步
解决方案似乎是使用不正确脚本

我改成renice -n 19 -p "$pid" && cpulimit -p "$pid" -l 20renice -n 19 -p $pid && cpulimit -p $pid -l 20

现在输出显示它按设计运行:

root@machine# /usr/local/bin/process-leash.sh 
+ sleep 10
+ for process_name in $PROCESSES_TO_WATCH
+ pid_list=("$(pgrep "$process_name")")
++ pgrep gnome-shell
+ '[' 1 -le 0 ']'
+ for pid in "${pid_list[@]}"
+ renice -n 19 -p 1797 3709 3074206
1797 (process ID) old priority 0, new priority 19
3709 (process ID) old priority 0, new priority 19
3074206 (process ID) old priority 0, new priority 19
+ cpulimit -p 1797 3709 3074206 -l 20
Process 1797 detected

与此同时,https://www.shellcheck.net/#它正在尖叫

$ shellcheck myscript
 
Line 14:
                renice -n 19 -p $pid && cpulimit -p $pid -l 20  
                                ^-- SC2086 (info): Double quote to prevent globbing and word splitting.
                                                    ^-- SC2086 (info): Double quote to prevent globbing and word splitting.

Did you mean: (apply this, apply all SC2086)
                renice -n 19 -p "$pid" && cpulimit -p "$pid" -l 20  

知道为什么变量上的引号会导致这个问题吗?

答案1

shellcheck 不知道你意味着,因此其通用的“使用双引号来防止分词”建议实际上对您不利。 的输出pgrep "$process_name"返回一个空格分隔的 PID 列表,其中需求在将其分配给数组时进行单词拆分,但由于您在分配期间用双引号括住该值,因此它始终保持为单个字符串。

相关内容