2014-09-29 77 views
1

我问了一个类似的问题here(你可能想检查)并没有收到答案,所以我要去尝试并简化它。每个真实条件执行一次命令,并等待,直到条件返回假,然后再次为真

#/bin/sh 

. /etc/ssh/autossh.conf 

if [[ $(ifconfig pdp_ip0 |grep inet) && ! $(ifconfig en0 |grep inet) ]]; 
then 
export NETTEST1=1; echo true 
else 
export NETTEST1=0; echo false 
fi 

if [[ ! $(ifconfig pdp_ip0 |grep inet) && $(ifconfig en0 |grep inet) ]]; 
then 
export NETTEST2=1; echo true 
else 
export NETTEST2=0; echo false 
fi 

while 
test $NETTEST1 -eq 1; 
do 
echo true 
done 

while 
test $NETTEST2 -eq 1; 
do 
echo true 
done 

这段代码的问题是它会在条件为真时继续执行命令。我需要它只对每个真实语句执行一次,然后等到语句为假然后再次为真。我一直在打我的头&我想知道如果它甚至possilbe。任何帮助总是感激。

我应该做这样的:

while true; do 
    while ifconfig pdp_ip0 |grep inet && ! ifconfig en0 |grep inet; 
    do sleep 1; done 
    while ! ifconfig pdp_ip0 |grep inet && ifconfig en0 |grep inet; do sleep 1; done 
    killall autossh; start-autossh 
    done; 
+0

的'ifconfig'命令被执行一次(也是唯一一次)在'if'声明。然后,脚本将退出(如果NETTEST1和NETTEST2都为零)或永远循环(如果NETTEST1或NETTEST2为1)。 – isedev 2014-09-29 23:22:47

+0

是的,但需要不断检查接口的状况。回声真正在while循环id把killall和我正在执行的另一个脚本。如果我这样做,它会不必要地杀死我的脚本。 – Geofferey 2014-09-29 23:41:00

+0

切题(我真的不明白):'如果[[! $(ifconfig pdp_ip0 | grep inet)&& $(ifconfig en0 | grep inet)]];'不必要的复杂(尽管它会起作用)。你可以更简单地写:“如果! ifconfig pdp_ip0 | grep -q inet && ifconfig en0 | grep -q inet;那么......' – rici 2014-09-30 00:04:22

回答

3

你要做的是在“边缘过渡”上触发某些命令;也就是说,一个条件从假转换为真。你可以做这样的事情(留出什么样的条件和动作是详细内容):

while true; do 
    while condition; do sleep 1; done 
    while ! condition; do sleep 1; done 
    do_what_needs_to_be_done 
done; 

假设条件(可以是任何管道)从来没有翻转在不到一秒钟的来回(或者你不介意在发生这种情况时错过了这个动作),当condition从失败变为成功时,这应该做do_what_needs_to_be_done

这个警告是“边缘转换”被怀疑的原因之一。尽管看起来网络向上或向下变化的一秒阈值可能很好,但通常需要几秒钟的时间,但您还需要考虑如果设备运行时脚本可能无法充分调度的问题在负载(或睡眠)下。但它可能会比没有好。

为清楚起见,我认为你有问题要稍微复杂一些,所以这里的一个稍微关节液:

# Do this forever 
while true; do 
    # Figure out which interface is up (if any) at the beginning 
    if ifconfig en0 | grep -q inet; then IF=en0 
    elif ifconfig pdp_ip0 | grep -q inet; then IF=pdp_ip0 
    else IF= 
    fi 

    # Some interface should be up at this point, but if not, 
    # there is no point waiting for it to go down. 
    if [[ $IF ]]; then 
    while ifconfig $IF | grep -q inet; do sleep 1; done 
    fi; 
    # Now whatever was up is down. Wait for something to come up. 
    while ! ifconfig en0 | grep -q inet && ! ifconfig pdp_ip0 | grep -q inet; do 
    sleep 1 
    done 

    # Some interface is up, so do the dirty deed 
    killall autossh; start-autossh 
    # And go back to waiting for the interface to drop. 
done 
+0

你可以检查我的主要帖子,并告诉如果这是我应该怎么做? – Geofferey 2014-09-30 01:49:49

+0

由于您不需要任何输出,因此您可能希望'grep -q'而不是'grep'。但另一个问题是,这两个条件并不相互颠倒:两个网络接口都可能关闭。我认为你可能想要做的事情是“虽然是真的;在当前网络接口启动时执行;做睡1;完成;虽然界面不起来;做睡1;完成; do_what_needs_to_be_done; done'。并发症是知道“当前”网络接口是什么;你会想要一个shell变量,它的值是'en0'或'pdp_ip0',并相应地设置它。 – rici 2014-09-30 01:54:53

+0

现在我更加困惑了。这是我在一段时间内用bash完成的最复杂的事情。目前的网络界面可以是任何时候的任何一个:/我甚至没有找到找出哪一个是活动界面的方法。如果我能找出哪一个是活动的,它会使这种方式更简单。当活动界面改变并重新启动时,我可以让它停止自动刷新。 – Geofferey 2014-09-30 02:00:42

1

我真的不明白你想要做什么。像这样?

do_test_1() { 
    { ifconfig pdp_ip0 | grep -q inet; } && 
    { ! ifconfig en0  | grep -q inet; } 
} 

if do_test_1; then 
    echo "true once" 
    while ! do_test_1; do 
     sleep 60 # or some amount 
    done 
    echo "true once again" 
fi 
+0

你检查了链接吗?它解释了我想要做什么以及为什么。你看起来像它会执行命令并等待60秒,如果条件仍然为真,则再次执行。我需要它执行一次真实的,然后等待虚假然后再次真实。谢谢你btw的答案,但我不知道它是否会工作。 – Geofferey 2014-09-29 23:45:50

相关问题