将命令行参数传递给 shell 脚本时发生 I/O 错误

将命令行参数传递给 shell 脚本时发生 I/O 错误

我编写了一个单行bash脚本(bright.sh)来手动调整显示亮度。

sudo sh -c 'echo "$1" > /sys/class/backlight/intel_backlight/brightness'

在这里,我从终端获取亮度值并将其作为参数传递给 echo 命令。但在运行脚本时,我收到如下 I/O 错误:

sh: echo: I/O error

我该怎么做才能从终端成功传递参数并手动控制亮度?示例用法可能如下所示:

./bright.sh 230

答案1

$1脚本中的将会sh -c扩展为第一个命令行参数脚本,而不是调用脚本的第一个命令行参数(因为sh -c脚本是单引号的)。

$1正确的解决方案不是将调用脚本中的值注入到sudo脚本中(这将允许各种有趣的代码注入漏洞),而是$1从外部脚本传递到内部脚本:

sudo sh -c 'printf "%s\n" "$1" > /sys/class/backlight/intel_backlight/brightness' sh "$1"

或者,sudo tee以 root 身份写入文件:

printf '%s\n' "$1" | sudo tee /sys/class/backlight/intel_backlight/brightness >/dev/null

如果打印到文件的数据始终是整数,请使用%d作为printf格式占位符而不是%s.

答案2

我可以通过将$1单个引号放在外面来解决这个问题。不确定这是否是最好的方法。

工作脚本现在看起来像 -

sudo sh -c 'echo '$1' > /sys/class/backlight/intel_backlight/brightness'

答案3

是的,你看到了问题(你的答案https://unix.stackexchange.com/a/481424/4778),但您仍然必须引用$1(以防万一)。并且不要忘记指定解释器 ( #!…)

«解决方案已被删除,因为它没有正确引用,并且存在安全错误。请参阅@Kusalananda 的回答。»

我们可以通过将字符串接触在一起来连接它们。双引号将扩展 $ 表达式,但单引号不会。在这种情况下,您可以将其全部放在双引号中,因为文本的其余部分没有$s,因此没有区别。

相关内容