OpenSolaris derivate (NexentaStor), python 2.5.5
我看过很多例子,很多似乎表明问题是死锁。我没有写信给标准输入,所以我认为问题是其中一个 shell 命令过早退出。
在 Popen 中执行的是:
ssh <remotehost> "zfs send tank/dataset@snapshot | gzip -9" | gzip -d | zfs recv tank/dataset
换句话说,登录到远程主机并(发送存储卷的复制流,将其通过管道传输到 gzip)将其通过管道传输到 zfs recv 以写入本地数据存储。
我已经看过关于缓冲区的解释,但我绝对没有填满这些,而且 gzip 过早地退出了,所以我认为 process.wait() 永远不会退出。
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
process.wait()
if process.returncode == 0:
for line in process.stdout:
stdout_arr.append([line])
return stdout_arr
else:
return False
这是我跑步并打断它时会发生的情况
# ./zfs_replication.py
gzip: stdout: Broken pipe
^CKilled by signal 2.
Traceback (most recent call last):
File "./zfs_replication.py", line 155, in <module>
Exec(zfsSendRecv(dataset, today), LOCAL)
File "./zfs_replication.py", line 83, in Exec
process.wait()
File "/usr/lib/python2.5/subprocess.py", line 1184, in wait
pid, sts = self._waitpid_no_intr(self.pid, 0)
File "/usr/lib/python2.5/subprocess.py", line 1014, in _waitpid_no_intr
return os.waitpid(pid, options)
KeyboardInterrupt
我也尝试使用 Popen.communicat() 方法,但如果 gzip 退出,它也会挂起。在这种情况下,我的命令 (zfs recv) 的最后一部分退出,因为本地数据集已被修改,因此不会应用增量复制流,因此即使这将得到修复,也必须有一种处理 gzip 损坏的方法管道?
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
stdout, stderr = process.communicate()
if process.returncode == 0:
dosomething()
else:
dosomethingelse()
运行时:
cannot receive incremental stream: destination tank/repl_test has been modified
since most recent snapshot
gzip: stdout: Broken pipe
^CKilled by signal 2.Traceback (most recent call last):
File "./zfs_replication.py", line 154, in <module>
Exec(zfsSendRecv(dataset, today), LOCAL)
File "./zfs_replication.py", line 83, in Exec
stdout, stderr = process.communicate()
File "/usr/lib/python2.5/subprocess.py", line 662, in communicate
stdout = self._fo_read_no_intr(self.stdout)
File "/usr/lib/python2.5/subprocess.py", line 1025, in _fo_read_no_intr
return obj.read()
KeyboardInterrupt