首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >os中的bash脚本--使网络设置发生更改

os中的bash脚本--使网络设置发生更改
EN

Stack Overflow用户
提问于 2014-05-06 20:25:49
回答 3查看 1.6K关注 0票数 0

我正在为geektool制作一个脚本,这样我就可以始终在我的桌面上看到我的DNS设置。它的工作原理是输出正确的命令,但是我得到了一个

代码语言:javascript
复制
command not found...

这是我的剧本

代码语言:javascript
复制
#!/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

下面是一个输出示例:

代码语言:javascript
复制
/Users/user/bin/netd3: line 15: networksetup -getdnsservers 'Wi-Fi': command not found

我可以运行which networksetup,它返回/usr/sbin/networksetup,但它没有运行。

我遗漏了什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 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循环中使用适当的引用(使用双引号和[@]而不是[*])。您还需要清理列表以删除有关禁用服务的标题和"*“。最后,我更喜欢$()而不是反向引号,所以我将继续修改它:

代码语言:javascript
复制
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
    ...

现在,对于命令本身,最好的选择取决于为什么要将它们放在变量中。最简单、最直接的选择是直接使用命令:

代码语言:javascript
复制
[[ ! $i =~ "*" || $1 =~ "W"  ]] && networksetup -getdnsservers "$i"

如果要使用命令的简写,请使用函数而不是变量:

代码语言:javascript
复制
getdns() {
    networksetup -getdnsservers "$@"
}
...
[[ ! $i =~ "*" || $1 =~ "W"  ]] && getdns "$i"

如果需要在执行之前存储整个命令(包括参数),请使用数组:

代码语言:javascript
复制
[[ ! $i =~ "*" || $1 =~ "W"  ]] && cmd=(networksetup -getdnsservers "$i") && "$cmd[@]"
票数 1
EN

Stack Overflow用户

发布于 2014-05-06 21:08:02

您的脚本试图将字符串networksetup -getdnsservers 'Wi-Fi'作为单个命令执行。使用

代码语言:javascript
复制
eval $cmd
票数 1
EN

Stack Overflow用户

发布于 2014-05-06 23:03:58

您还可以在脚本的顶部,在#!/bin/bash下面添加以下内容

代码语言:javascript
复制
PATH=/bin:/usr/bin:/sbin:/usr/sbin export PATH
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23504181

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档