每个真实条件执行一次命令&等到条件返回false然后再次返回true

时间:2014-09-29 23:19:57

标签: bash shell loops networking conditional-statements

我问了一个类似的问题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

这段代码的问题是它会在条件为真时继续执行命令。我需要它只对每个true语句执行一次,然后等到语句为false然后再次为true。我一直在打它过头。我想知道它是否可能。任何帮助总是受到赞赏。

我应该这样做:

    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;

2 个答案:

答案 0 :(得分:3)

你要做的是在“边缘过渡”上触发一些命令;也就是说,条件从false转换为true。你可以做到这样的事情(省略条件和行动的细节):

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

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

这一警告是怀疑“边缘过渡”的原因之一。虽然网络上升或下降的一秒阈值似乎很好,通常至少需要几秒钟,但您还需要考虑如果设备运行,您的脚本可能无法经常安排的问题负载(或睡眠)。但它可能会比没有好。

为了清楚起见,我认为你遇到的问题稍微复杂一点,所以这里有一个更明确的解决方案:

# 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

答案 1 :(得分:2)

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

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