2011-11-05 216 views
2

我正在处理一个非常简单的脚本,但由于某些原因它的一部分似乎异步运行。Bash脚本不会等待,直到命令正确执行

singlePartDevice() { 
# http://www.linuxquestions.org/questions/linux-software-2/removing-all-partition-from-disk-690256/ 
# http://serverfault.com/questions/257356/mdadm-on-ubuntu-10-04-raid5-of-4-disks-one-disk-missing-after-reboot 
# Create single partition 
parted -s "$1" mklabel msdos 
# Find size of disk 
v_disk=$(parted -s "$1" print|awk '/^Disk/ {print $3}'|sed 's/[Mm][Bb]//') 
parted -s "$1" mkpart primary ext3 4096 ${v_disk} 
parted -s "$1" set 1 raid on 
return 0 
} 

singlePartDevice "/dev/sdc" 
singlePartDevice "/dev/sdd" 

#/dev/sdc1 exists but /dev/sdd1 does not exist 
sleep 5s 
#/dev/sdc1 exists AND /dev/sdd1 does also exist 

正如您在睡眠之前所看到的,脚本只是部分完成了工作。如何让我的脚本等到分手完成其工作后才能成功?

回答

6

(我假设你在Linux上工作,由于在你的问题中的链接)

我不是很熟悉parted,但我相信,该分区的设备节点不直接创造的 - 它们是由udev创建,它本质上是一个异步过程:

  • parted创建一个分区
  • 内核更新其内部状态
  • 内核通知udev守护进程(udevd
  • udevd检查其规则文件(通常在/etc/udev/)并创建相应的设备节点

此过程允许将设备节点处理策略与内核清晰分离,该内核是Good Thing(TM)。不幸的是,它也引入了相对不可预知的延迟。

一种可能的方法来处理这个是让你的脚本等待设备节点出现:

while [ ! -e "/dev/sdd1" ]; do sleep 1; done 
2

假设所有你想要做的就是确保分区程序之前创建的,有几个不同的方法

  1. 检查是否处理分手已经移动到下一个步骤

  2. 前完成

    在转到下一步之前检查设备是否准备就绪(您需要检查语法)。例如 直到[-f的/ dev/SDC & & -f的/ dev/SDD] 睡眠5