如何在Plumbum中模拟反引号子shell功能?
问题
想要用Plumbum实现类似Shell命令的功能:
foo $(date +%H%M%S) # 或等价写法 foo `date +%H%M%S`
其中foo可以看作类似mkdir的命令,要求实现一个可复用的Plumbum对象,每次调用时都会传入当前最新的时间字符串(而非固定值)。
尝试过以下代码,运行报错:
#!/usr/bin/env python3 from plumbum import local import time s = local["sh"] f = s["-c", "mkdir", "$(date +%H%M%S)"] for i in range(0,10): f() time.sleep(1)
错误信息:
plumbum.commands.processes.ProcessExecutionError: Unexpected exit code: 1 Command line: | /usr/bin/sh -c mkdir '$(date +%H%M%S)' Stderr: | mkdir: missing operand | Try 'mkdir --help' for more information.
已知可以用Python的time.localtime()计算时间,但直接赋值会导致每次调用都是同一个值;也可以生成Shell脚本文件,但需要后续清理,希望用Plumbum原生方式解决。
解决方法
方法1:利用Plumbum的延迟求值参数(推荐)
Plumbum支持将函数作为命令参数,每次调用命令时会自动执行函数,获取最新的参数值,完全符合需求:
#!/usr/bin/env python3 from plumbum import local import time from datetime import datetime # 定义获取当前时间的函数,每次调用返回最新的时间字符串 def get_current_time(): return datetime.now().strftime("%H%M%S") # 创建可复用的命令对象,参数绑定为上述函数 mkdir_cmd = local["mkdir"][get_current_time] # 测试调用,每次都会创建以当前时间命名的目录 for _ in range(10): mkdir_cmd() time.sleep(1)
这种方式不需要依赖Shell,完全是Plumbum原生特性,更符合Python风格,且灵活可控。
方法2:正确使用Shell子命令
如果一定要依赖date命令而非Python内置的时间处理,需要修正sh -c的参数传递方式:-c后面必须是完整的命令字符串,而非拆分的命令和参数:
#!/usr/bin/env python3 from plumbum import local import time sh = local["sh"] # 将完整命令作为单个字符串传给sh -c mkdir_cmd = sh["-c", "mkdir $(date +%H%M%S)"] for _ in range(10): mkdir_cmd() time.sleep(1)
之前的错误原因是:sh -c的第一个参数是要执行的命令内容,后续参数会被当作$0、$1等变量,而非命令的参数。之前的写法相当于让Shell执行mkdir命令,没有传入任何参数,因此报错"missing operand"。
方法3:直接使用plumbum.cmd模块
如果不需要local的环境隔离,也可以直接导入plumbum.cmd中的命令,同样结合延迟函数参数:
#!/usr/bin/env python3 from plumbum.cmd import mkdir import time from datetime import datetime def get_current_time(): return datetime.now().strftime("%H%M%S") mkdir_cmd = mkdir[get_current_time] for _ in range(10): mkdir_cmd() time.sleep(1)
内容的提问来源于stack exchange,提问作者user1908704
相关产品推荐
相关产品推荐

