我正在为geektool制作一个脚本,这样我就可以始终在我的桌面上看到我的DNS设置。它的工作原理是输出正确的命令,但是我得到了一个
command not found...这是我的剧本
#!/bin/bash
IFS='
'
getdns='networksetup -getdnsservers'
# [-getdnsservers networkservice]
setdns='networksetup -setdnsservers'
# usage [-setdnsservers networkservice dns1 [dns2] [...]]
services=(`networksetup -listallnetworkservices`)
for i in ${services[*]}; do
# original setup, which returns the correct command
# [[ ! $i =~ "*" || $1 =~ "W" ]] && echo $getdns \"$i\"
# command that fails when attempting to execute string...
# # [[ ! $i =~ "*" || $1 =~ "W" ]] && echo `$getdns \"$i\"`
# my attempt to concatenate the strings
[[ ! $i =~ "*" || $1 =~ "W" ]] && cmd="$getdns '$i'" ;echo `$cmd`
done下面是一个输出示例:
/Users/user/bin/netd3: line 15: networksetup -getdnsservers 'Wi-Fi': command not found我可以运行which networksetup,它返回/usr/sbin/networksetup,但它没有运行。
我遗漏了什么?
发布于 2014-05-07 02:07:02
像这样在变量中存储命令是有问题的(请参阅BashFAQ #50:我试图在变量中放置一个命令,但是复杂的情况总是失败的!)。最大的问题是,引号是在变量被替换之前进行评估的,因此在变量中嵌入引号(例如,cmd="$getdns '$i'"中的单引号)并不能达到预期的效果。
在您的特殊情况下,还有另外一个问题:您将IFS设置为仅为linefeed,因此当shell展开$cmd时,它通过查找linefeed将其拆分为“word”--没有任何,因此它错误了命令本身的一部分应该是参数(-getdnsservers和'Wi-Fi')。也就是说,它不使用参数" -getdnsservers“和”Wi“运行命令"networksetup”,而是尝试运行"networksetup -getdnsservers‘Wi“作为命令。
我会提出几个建议来清理这件事。首先,在获得服务列表之后,将IFS设置为其通常的值。这也意味着您需要在for循环中使用适当的引用(使用双引号和[@]而不是[*])。您还需要清理列表以删除有关禁用服务的标题和"*“。最后,我更喜欢$()而不是反向引号,所以我将继续修改它:
saveIFS="$IFS"
IFS='
'
services=( $(networksetup -listallnetworkservices | sed '/An asterisk ([*]) denotes that a network service is disabled./d; s/^[*]//') )
IFS="$saveIFS"
for i in "${services[@]}"; do
...现在,对于命令本身,最好的选择取决于为什么要将它们放在变量中。最简单、最直接的选择是直接使用命令:
[[ ! $i =~ "*" || $1 =~ "W" ]] && networksetup -getdnsservers "$i"如果要使用命令的简写,请使用函数而不是变量:
getdns() {
networksetup -getdnsservers "$@"
}
...
[[ ! $i =~ "*" || $1 =~ "W" ]] && getdns "$i"如果需要在执行之前存储整个命令(包括参数),请使用数组:
[[ ! $i =~ "*" || $1 =~ "W" ]] && cmd=(networksetup -getdnsservers "$i") && "$cmd[@]"发布于 2014-05-06 21:08:02
您的脚本试图将字符串networksetup -getdnsservers 'Wi-Fi'作为单个命令执行。使用
eval $cmd发布于 2014-05-06 23:03:58
您还可以在脚本的顶部,在#!/bin/bash下面添加以下内容
PATH=/bin:/usr/bin:/sbin:/usr/sbin export PATHhttps://stackoverflow.com/questions/23504181
复制相似问题