cha*_*e55 32 bash shell-script unmounting
我需要在我的脚本中卸载某些内容,但有时它会在所有数据完成复制之前卸载并导致卸载失败。我寻找一种方法来进行“阻塞”卸载,但我什么也没找到。所以,我试图编写一个脚本来循环直到它可以被卸载,但它不起作用。
while [ `sudo umount mount` ]
do
sleep 0.1
done
rmdir mount
Run Code Online (Sandbox Code Playgroud)
运行输出时:
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
Run Code Online (Sandbox Code Playgroud)
它不应该循环直到返回值为sudo umount mount
0,这意味着它已成功卸载吗?
Sté*_*las 66
该[
命令是评估条件表达式。这里没有用。
因为umount
在其标准输出上不输出任何内容(错误转到 stderr),所以`sudo umount mount`
扩展为空。
所以它就像:
while [ ]
do
sleep 0.1
done
Run Code Online (Sandbox Code Playgroud)
该[
命令,当没有在旁边传递任何参数[
并]
返回false(非零退出状态)时,因此您不会进入循环。
即使umount
在 stdout 上输出了错误,使用该[
命令也没有意义,因为该输出产生的词永远不会构成有效的条件表达式。
在这里你想要:
until sudo umount mount
do
sleep 0.1
done
Run Code Online (Sandbox Code Playgroud)
也就是说,您要检查 sudo/umount 的退出状态,而不是[
命令的退出状态。
如果您想检查是否umount
在其 stderr 上输出任何错误或警告,那么这[
可能很有用。的-n "some-string"
是通过所识别的条件表达式[
命令测试是否"some-string"
是空的或没有,所以这样的:
while [ -n "$(sudo umount mount 2>&1 > /dev/null)" ]; do
sleep 0.1
done
Run Code Online (Sandbox Code Playgroud)
但是寻找错误或警告消息的存在通常是一个坏主意。该umount
命令通过退出代码告诉我们它是否成功,这更可靠。它可能会成功并仍然输出一些警告消息。它可能会失败并且不输出错误(比如它被杀死时)。
在这种特殊情况下,请注意这umount
可能会失败,因为目录未挂载,在这种情况下您将永远循环,因此您可以尝试另一种方法,例如:
while mountpoint -q mount && ! sudo umount mount; do
sleep 0.1
done
Run Code Online (Sandbox Code Playgroud)
或者,如果“mount”可能被挂载多次,而您想将它们全部卸载:
while mountpoint -q mount; do
sudo umount mount || sleep 0.1
done
Run Code Online (Sandbox Code Playgroud)
小智 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
}
Run Code Online (Sandbox Code Playgroud)
不需要睡觉