将命令线字符串解析为子过程列表的最简单方法?

发布于 2025-02-12 13:25:43 字数 1320 浏览 1 评论 0原文

我正在尝试使用subprocess.run()来弄清楚如何运行此命令:

cmd = 'find / \( -path /mnt -prune -o -path /dev -prune -o -path /proc -prune -o -path /sys -prune \) -o ! -type l -type f -or -type d -printf "depth="%d/"perm="%m/"size="%s/"atime="%A@/"mtime"=%T@/"ctime"=%C@/"hardlinks"=%n/"selinux_context"=%Z/"user="%u/"group="%g/"name="%p/"type="%Y\\n'

我已经将命令放入列表中,甚至删除项目等:

cmd = [
    'find',
    '/',
    '\( -path /mnt -prune -o -path /dev -prune -o -path /proc -prune -o -path /sys -prune \)',
    '-o',
    '! -type l',
    '-type f',
    '-or',
    '-type d'
]

我尝试使用使用命令运行该命令/bin/bash

cmd = '/bin/bash -c find / \( -path /mnt -prune -o -path /dev -prune -o -path /proc -prune -o -path /sys -prune \) -o ! -type l -type f -or -type d -printf "depth="%d/"perm="%m/"size="%s/"atime="%A@/"mtime"=%T@/"ctime"=%C@/"hardlinks"=%n/"selinux_context"=%Z/"user="%u/"group="%g/"name="%p/"type="%Y\\n'

没关系。我尝试过的一切都行不通。我根本没有输出,或者它在主目录中列出了文件,或者我会遇到错误,例如:b'find:路径必须先于表达式:! -type l \ nusage:find [-h] [-l] [-p] [-olevel] [-d帮助| tree | search | state | stat | rates | opt | opt | exec] [path ...] [path ...] [expression] \ n'

是否有任何简单的方法可以采用在命令行中工作的命令,然后将字符串解析到任何列表元素subprocess.run()想要的内容中?

I'm trying to figure out how to run this command using subprocess.run():

cmd = 'find / \( -path /mnt -prune -o -path /dev -prune -o -path /proc -prune -o -path /sys -prune \) -o ! -type l -type f -or -type d -printf "depth="%d/"perm="%m/"size="%s/"atime="%A@/"mtime"=%T@/"ctime"=%C@/"hardlinks"=%n/"selinux_context"=%Z/"user="%u/"group="%g/"name="%p/"type="%Y\\n'

I've put the command into a list, even removing items, etc:

cmd = [
    'find',
    '/',
    '\( -path /mnt -prune -o -path /dev -prune -o -path /proc -prune -o -path /sys -prune \)',
    '-o',
    '! -type l',
    '-type f',
    '-or',
    '-type d'
]

I've tried running the command using /bin/bash:

cmd = '/bin/bash -c find / \( -path /mnt -prune -o -path /dev -prune -o -path /proc -prune -o -path /sys -prune \) -o ! -type l -type f -or -type d -printf "depth="%d/"perm="%m/"size="%s/"atime="%A@/"mtime"=%T@/"ctime"=%C@/"hardlinks"=%n/"selinux_context"=%Z/"user="%u/"group="%g/"name="%p/"type="%Y\\n'

Doesn't matter. Everything I've tried does not work. Either I get no output at all, or it lists the files in my home directory, or I get an error, e.g.: b'find: paths must precede expression: ! -type l\nUsage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]\n'

Is there any easy way to take a command that works at the command line and just parse the string into whatever list elements subprocess.run() wants?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

十秒萌定你 2025-02-19 13:25:44

shlex.split()

解析printf字符串中的错误引号后,我们得到:

cmd = r'''
find / \( -path /mnt -prune -o -path /dev -prune -o -path /proc -prune -o -path /sys -prune \) -o ! -type l -type f -or -type d -printf 'depth=%d/perm=%m/size=%s/atime=%A@/mtime=%T@/ctime=%C@/hardlinks=%n/selinux_context=%Z/user=%u/group=%g/name=%p/type=%Y\\n'
'''
print(shlex.split(cmd))

...它发出完全正确的结果,subprocess.call()>正确使用它。


用手手工构建正确的命令行,

手工做到这一点:

cmd = [
    'find', '/',
    '(',
             '-path', '/mnt',  '-prune',
       '-o', '-path', '/dev',  '-prune',
       '-o', '-path', '/proc', '-prune',
       '-o', '-path', '/sys',  '-prune',
    ')',
    '-o', '!', '-type', 'l',
    '-type', 'f',
    '-or',
    '-type', 'd',
    '-printf', 'depth=%d/perm=%m/size=%s/atime=%A@/mtime=%T@/ctime=%C@/hardlinks=%n/selinux_context=%Z/user=%u/group=%g/name=%p/type=%Y\n'
]

注意:

  • 句法引号会改变外壳的解析模式,它们不会成为数据的一部分。 “ foo”刚变成foo; “ foo” bar“ baz”变为foobarbaz。因此,您不能/不应该/不尝试将这些引号放入Python传递的数据中。
  • 这也是\(:Backslash是 shell shell <也是如此。 语法
  • /em > 在外壳中' - type','f',两个单独的单词。

Parsing With shlex.split()

After fixing the incorrect quotes in your printf string, we get:

cmd = r'''
find / \( -path /mnt -prune -o -path /dev -prune -o -path /proc -prune -o -path /sys -prune \) -o ! -type l -type f -or -type d -printf 'depth=%d/perm=%m/size=%s/atime=%A@/mtime=%T@/ctime=%C@/hardlinks=%n/selinux_context=%Z/user=%u/group=%g/name=%p/type=%Y\\n'
'''
print(shlex.split(cmd))

...which emits an entirely correct result, and subprocess.call() works with it properly.


Building A Correct Command Line By Hand

In terms of what it looks like to do this by hand:

cmd = [
    'find', '/',
    '(',
             '-path', '/mnt',  '-prune',
       '-o', '-path', '/dev',  '-prune',
       '-o', '-path', '/proc', '-prune',
       '-o', '-path', '/sys',  '-prune',
    ')',
    '-o', '!', '-type', 'l',
    '-type', 'f',
    '-or',
    '-type', 'd',
    '-printf', 'depth=%d/perm=%m/size=%s/atime=%A@/mtime=%T@/ctime=%C@/hardlinks=%n/selinux_context=%Z/user=%u/group=%g/name=%p/type=%Y\n'
]

Note:

  • Syntactic quotes change the shell's parsing mode, they don't become part of the data. "foo" just becomes foo; "foo"bar"baz" becomes foobarbaz. So you can't/shouldn't/don't try to put those quotes into the data that Python is passing in.
  • This is true also for \(: the backslash is shell syntax. It doesn't actually become one of find's arguments, so you leave it out.
  • Any space that isn't quoted or escaped separates words; so -type f in shell is '-type', 'f', two separate words.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文