gpt4 book ai didi

脚本问题中的bash参数变量

转载 作者:行者123 更新时间:2023-11-29 09:02:39 33 4
gpt4 key购买 nike

我有一个我编写的脚本,用于切换到 root 或以 root 身份运行命令而无需密码。我编辑了我的/etc/sudoers 文件,以便我的用户 [matt] 有权在没有密码的情况下运行/bin/su。这是我的脚本“s”内容:

matt: ~ $ cat ~/bin/s
#!/bin/bash

[ "$1" != "" ] && c='-c'

sudo su $c "$*"

如果没有参数 [只需 s],它基本上会调用 sudo su,无需密码即可进入 root。但是如果我输入参数,$c 变量等于“-c”,这会使 su 执行单个命令。

它工作得很好,除非我需要使用空格。例如:

matt: ~ $ touch file\ with\ spaces
matt: ~ $ s chown matt file\ with\ spaces
chown: cannot access 'file': No such file or directory
chown: cannot access 'with': No such file or directory
chown: cannot access 'spaces': No such file or directory
matt: ~ $ s chown matt 'file with spaces'
chown: cannot access 'file': No such file or directory
chown: cannot access 'with': No such file or directory
chown: cannot access 'spaces': No such file or directory
matt: ~ $ s chown matt 'file\ with\ spaces'
matt: ~ $

我该如何解决这个问题?

另外,$*$@ 有什么区别?

最佳答案

啊,引用很有趣。通常,@John 建议的方法适用于此:使用 "$@",它不会尝试解释(并被混淆)参数中的空格和其他有趣的字符。然而,在这种情况下,这是行不通的,因为 su 的 -c 选项期望整个命令作为单个参数传递,然后它将启动一个新的 shell 来解析命令(包括被空格等混淆) .为了避免这种情况,您实际上需要重新引用要传递给 su -c 的字符串中的参数。 bash 的 printf 内置函数可以做到这一点:

#!/bin/bash

if [ $# -gt 0 ]; then
sudo su -c "$(printf "%q " "$@")"
else
sudo su
fi

让我回顾一下这里发生的事情:

  1. 您运行一个命令,例如 s chown matt file\with\spaces
  2. bash 将其解析为单词列表:“s”“chown”“matt”“带空格的文件”。请注意,此时您键入的转义符已被删除(尽管它们具有预期效果:使 bash 将这些空格视为参数的一部分,而不是参数之间的分隔符)。
  3. 当 bash 解析脚本中的 printf "%q ""$@" 命令时,它将 "$@" 替换为脚本的参数,参数为完好无损。它等同于 printf "%q ""chown""matt""file with spaces"
  4. printf 将格式字符串“%q”解释为“以引号形式打印每个剩余参数,其后有一个空格”。它打印:“chown matt file\with\spaces ”,本质上是重建原始命令行(它在末尾有一个额外的空格,但事实证明这不是问题)。
  5. 然后将其作为参数传递给 sudo(由于 $() 构造周围有双引号,它将被视为 sudo 的单个参数)。这相当于运行 sudo su -c "chown matt file\with\spaces "
  6. sudo 运行 su,并传递它获得的其余参数列表,包括完全转义的命令。
  7. su 运行一个 shell,它还会传递其余的参数列表。
  8. shell 执行它作为 -c 的参数获得的命令:chown matt file\with\spaces。在正常的解析过程中,它会将未转义的空格解释为参数之间的分隔符,将转义的空格解释为参数的一部分,并且会忽略末尾的额外空格。
  9. shell 运行 chown,参数为“matt”和“file with spaces”。这符合您的预期。

bash 解析不是一个问题吗?

关于脚本问题中的bash参数变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5809783/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com