Bash脚本编写-循环直到返回值为0


25

我需要在脚本中卸载某些内容,但有时需要先卸载所有数据,然后再完成卸载,导致卸载失败。我正在寻找一种方法来进行“阻止”卸载,但是我什么也没找到。因此,我尝试编写一个脚本来循环,直到可以将其卸载为止,但是它不起作用。

while [ `sudo umount mount` ]
do
    sleep 0.1
done
rmdir mount

运行时输出:

umount: /home/evantandersen/mount: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
rmdir: failed to remove `mount': Device or resource busy

它不应该循环直到返回值sudo umount mount0表示已成功卸载吗?

Answers:


59

[命令用于评估条件表达式。在这里没有用。

由于umount在标准输出上不输出任何内容(错误归于stderr),因此`sudo umount mount`扩展为空。

所以就像:

while [ ]
do
  sleep 0.1
done

[命令时没有通过任何参数旁边[,并]返回(非零退出状态),这样你就不会进入循环。

即使umount在stdout上输出了错误,使用该[命令也没有意义,因为该输出产生的单词永远不会构成有效的条件表达式。

您要在这里:

until sudo umount mount
do
  sleep 0.1
done

也就是说,您要检查sudo / umount而不是[命令的退出状态。

如果要检查umount在stderr上是否输出任何错误或警告,那[可能是有用的地方。的-n "some-string"是通过所识别的条件表达式[命令测试是否"some-string"是空的或没有,所以这样的:

while [ -n "$(sudo umount mount 2>&1 > /dev/null)" ]; do
  sleep 0.1
done

但是寻找错误或警告消息通常不是一个好主意。该umount 命令告诉我们它是否以退出代码成功,这要可靠得多。它可能会成功,但仍会输出一些警告消息。它可能会失败,并且不会输出错误(例如被杀死时)。

在这种特殊情况下,请注意,umount由于未装载目录,这可能会失败,并且在这种情况下您将永远循环,因此您可以尝试另一种方法,例如:

while mountpoint -q mount && ! sudo umount mount; do
  sleep 0.1
done

或者,如果“ mount”可能已经安装了好几次,而您想全部卸载:

while mountpoint -q mount; do
  sudo umount mount || sleep 0.1
done

棒极了!
charliehorse55 2013年

1
1用于解释使用之间的差[[[或没有。我希望有关bash条件的典型手册页,GNU和/或TLDP示例涵盖这样的细节
renoirb

5

可重用的功能,并且将在“ n”秒内超时

_umount() {
    [[ $# -lt 2 ]] && { 
        echo "Usage: ${FUNCNAME} <timeout_secs> <mnt_point>"; return 1
    }
    timeout=$(($(date +%s) + ${1}))
    until umount "${2}" 2>/dev/null || [[ $(date +%s) -gt $timeout ]]; do
       :
    done
}

不用睡觉


1
[[...]]ksh/ bash/ zsh特定的,所有这些都具有$SECONDS特殊的变量,所以你可以这样做:SECONDS=0; until umount... || ((SECONDS > $1)); do..
斯特凡Chazelas

请记住,mount remount,ro使用Intenso Micro Line USB记忆棒在mips设备anno 2009上执行的命令可能需要23甚至30+秒钟才能完成。
Pro Backup
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.