大多数解析/proc/cmdline的脚本将其分解为单词,然后使用case语句过滤掉参数,例如:
CMDLINE="quiet union=aufs wlan=FOO"
for x in $CMDLINE
do
»···case $x in
»···»···wlan=*)
»···»···echo "${x//wlan=}"
»···»···;;
»···esac
done
问题是当WLAN ESSID有空格时,用户希望设置wlan='FOO
BAR'(类似于shell变量),然后用上面的代码得到'FOO
的意外结果,因为for循环在空格上分裂。
有没有更好的方法来从shell脚本中解析/proc/cmdline
,而几乎没有对它求值?
或者有一些引用技巧吗?我在想,我也许可以让用户实体引用空格,并像这样解码:/bin/busybox httpd -d "FOO%20BAR"
。或者这是一个糟糕的解决方案吗?
8条答案
按热度按时间hwamh0ep1#
有几种方法:
1.第一个月
cat /proc/PID/cmdline | xargs -0 echo
这在大多数情况下都可以使用,但是当参数中有空格时会失败,但是我确实认为会有比使用
/proc/PID/cmdline
更好的方法。lsmepo6l2#
zzoitvuj3#
最常见的是,当空格不可接受时使用
\0ctal
转义序列。在Bash中,
printf
可以用来取消转义它们,例如:zmeyuzjn4#
由于您希望shell解析/proc/cmdline内容,因此很难避免对它求值。
这显然是危险的,因为它会盲目地运行在内核命令行上指定的任何东西,比如
quiet union=aufs wlan=FOO ) ; touch EVIL ; q=( q
。转义空格(\x20)听起来是最直接、最安全的方法。
另一个重要的选择是使用一些解析器,它们理解类似shell的语法。在这种情况下,你可能不再需要shell了。例如,使用python:
zlwx9yxi5#
使用
xargs -n1
:pvabu6sv6#
您可以使用bash执行类似下面的操作,它会将这些参数转换为$cmdline_union和$cmdline_wlan这样的变量:
然后,您可以引用和/或转义内容,就像在普通shell中一样。
rsl1atfo7#
豪华:
你可以定义一个函数,并给予$CMDLINE unquoted 作为函数的参数,然后调用shell的解析机制,注意,你应该在shell上测试一下-- zsh在引用方面做了一些有趣的事情;- ).
然后,您可以告诉用户像在shell中那样引用:
(posh- 符合策略的普通 shell ,该 shell 去除了标准POSIX以外的任何功能)
lnlaulya8#
我发现here是使用awk实现这一功能的好方法,但不幸的是,它只能使用双引号: