我目前正在将一个bash脚本转换为python,并且在bash中有一个命令:mv -i
我知道这mv意味着MOVE,但我不确定如何mv -i在Python中使用.我也试过man move但是不能理解它.
通常,您不希望" mv -i在Python中使用"; 你想在本机中使用命令os或shutil在本地执行操作.
但是,如果你不希望使用mv -i,你做的方式是什么都一样:
subprocess.check_call(['mv', '-i', srcpath, dstpath])
Run Code Online (Sandbox Code Playgroud)
请记住,重点-i是它是互动的.引自BSD手册页:
导致mv在移动将覆盖现有文件的文件之前写入标准错误的提示.如果标准输入的响应以字符
y' orY' 开头,则尝试移动.
所以,你可能想让它的stdin和stdout通过,所以用户可以直接与它交互.除非您想要弹出GUI警报而不是控制台提示,否则您将不得不手动附加管道和处理事物,这将不会很有趣.
如果你只想编写与"基本相同"的原生Python代码mv -i,那不是太难:
if os.path.isfile(dstname):
yesno = input("'{}' already exists. Replace? ".format(dstpath))
if yesno.upper()[0] != 'Y':
raise FileExistsError("'{}': already exists".format(dstpath))
shutil.move(srcpath, dstpath)
Run Code Online (Sandbox Code Playgroud)
但是,这并不完全相同.最严重的是,它具有真实命令所没有的竞争条件(如果您dstname在isfile呼叫和move呼叫之间移动不同的文件,它将被覆盖).但是也有各种各样的微不足道的差异,比如它不处理移动多个源文件的情况.
如果你想要完全重现本mv -i机Python 的行为,它将是这样的:
fd = -1
try:
try:
fd = os.open(dstpath, os.O_WRONLY | os.O_CREAT | os.O_EXCL)
except OSError as e:
if e.errno == errno.EEXIST:
yesno = input("'{}' already exists. Replace? ".format(dstpath))
if yesno.upper()[0] != 'Y': raise e
os.rename(srcpath, dstpath)
finally:
if fd > 0: os.close(fd)
Run Code Online (Sandbox Code Playgroud)
除了你还需要代码来处理dstpath一个目录的情况,所以你也想要fstat在那里添加一个,并且......真的,你想要读源到C语言的开源实现mv,而不是猜测.
更重要的是,你为什么要首先做一个mv -i?如果你看一下你的程序实际在做什么,以及用户体验应该是什么,那么这很可能不是正确的答案.
例如,如果您要求用户输入文件名以保存数据,您可以将数据写入临时文件,然后将mv -i其写入用户的文件名...但是用户可能更愿意立即验证覆盖,而不是等到你已经生成了tempfile(特别是如果需要很长时间).
| 归档时间: |
|
| 查看次数: |
788 次 |
| 最近记录: |