python - 命令在 bash 终端中工作,但在 Python subprocess.Popen() 中不工作;得到一个'路径必须在表达式之前:'%p'错误
问题描述
我正在尝试查找最近修改过的文件的位置。在 bash 中,您可以通过
find /media/tiwa/usb/ -not -path '*/\.*' -type f -printf '%T@ %p\n' 2> >(grep -v 'Permission denied' >&2) | sort -k1,1nr | head -1`
确实,在我的系统上,这会返回
1527379702.1060795850 /media/tiwa/usb/hi.txt
我打算获取此命令的输出(在 Python 中),将其拆分为第一个空格,然后解析文件路径(是的,我可以使用awk
,但无论如何都会抛出相同的错误)。所以我做了
import subprocess
bashCommand = "find /media/tiwa/usb/ -not -path '*/\.*' -type f -printf '%T@ %p\n' 2> >(grep -v 'Permission denied' >&2) | sort -k1,1nr | head -1"
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output, error = process.communicate()
print(output)
但这打印出来
find: paths must precede expression: `%p'
转义反斜杠似乎也无济于事。
是什么导致了这个问题,我该如何解决?
解决方案
你有一个完整的 shell 命令行,而不仅仅是一个命令加上它的参数,这意味着你需要使用该shell=True
选项而不是(错误地)将字符串拆分为多个字符串。(Python 字符串拆分不等同于 shell 的分词,后者更加复杂和复杂。)此外,由于您的命令行包含bash
-specific 功能,因此您需要明确Popen
使用/bin/bash
,而不是默认使用/bin/sh
.
import subprocess
bashCommand = "find /media/tiwa/usb/ -not -path '*/\.*' -type f -printf '%T@ %p\n' 2> >(grep -v 'Permission denied' >&2) | sort -k1,1nr | head -1"
path_to_bash = "/bin/bash" # or whatever is appropriate
process = subprocess.Popen(bashCommand,
stdout=subprocess.PIPE,
shell=True,
executable=path_to_bash)
output, error = process.communicate()
print(output)
(但是,使用它os.walk()
来获取每个文件,并用于os.stat()
获取每个相关文件的修改时间,并且只保留迄今为止找到的最新文件,直到您检查了每个文件,它会更简单、更健壮。
import os
newest = (0, "")
for (dir, subdirs, fname) in os.walk("/media/tiwa/usb"):
if fname.startswith(".") or not os.path.isfile(fname):
continue
mtime = os.stat(fname).st_mtime
if mtime > newest[0]:
newest = (mtime, fname)
也许
def names_and_times(d):
for (_, _, fname) in os.walk(d):
if fname.startswith(".") or not os.path.isfile(fname):
continue
yield (os.stat(fname).st_mtime), fname)
newest = max(names_and_times("/media/tiwa/usb"))
)
请记住,上述任何一种方法都只会返回一个具有最新修改时间的文件。
推荐阅读
- android - Ionic - Uncaught SyntaxError: Unexpected token On APK
- reactjs - 在单元测试中承诺初始化警告后捕获错误
- jenkins - 如何从 Jenkins 检索测试日志
- api - 消息将如何显示在 M365 管理中心
- c# - 如何通过名称动态访问类属性
- php - 将非字母数字字符转换为 unicode 代码
- java - 访问被拒绝在 Android 11 上找到属性“ro.serialno”
- applescript - 如何使用苹果脚本从对话框面板中选择文件?
- android - 您如何为付费的亚马逊应用程序实施许可?
- c++ - 可以在函数内部执行 new 并返回指向它的指针吗?