Как запустить команду ls с subprocess.check_call, содержащим заполнитель? - PullRequest
1 голос
/ 09 июля 2020

В python (3.6.8) вы можете использовать subprocess.check_call для запуска команды, например

import subprocess
subprocess.check_call("ls -l /home/user".split())

, которая, в этом примере, распечатывает содержимое домашнего каталога:

...
drwx------ 25 user user       4096 Jan 27 16:31 Music
-rw-r--r--  1 user user          0 Jul  9 11:06 nse.file.zip
-rw-rw-r--  1 user user 1938520956 Jul  8 16:59 nse.file.zip.1
-rw-------  1 user user  514916418 Jul  9 11:15 nse.file.zip.part
drwxr-xr-x  5 user user      12288 Mar 11 14:32 Pictures
drwxr-xr-x  8 user user       4096 Mar  9 06:36 Private
drwxr-xr-x  2 user user       4096 Jul 30  2018 Public
...

Но, напротив, когда вы хотите использовать заполнители для перечисления нескольких файлов одновременно, это больше не работает:

subprocess.check_call("ls -l /home/user/nse*".split())

или

subprocess.check_call("ls -l '/home/user/nse*'".split())

В обоих случаях я получаю сообщение об ошибке

CalledProcessError: Command '['ls', '-l', '/home/user/nse*']' returned non-zero exit status 2.

или

CalledProcessError: Command '['ls', '-l', "'/home/user/nse*'"]' returned non-zero exit status 2.

Что мне не хватает? Как решить эту проблему?

Ответы [ 2 ]

2 голосов
/ 09 июля 2020

Вам не хватает того факта, что расширение подстановочных знаков (понимание того, что означает *) не выполняется ls, а выполняется оболочкой. Когда вы запускаете что-то вроде ls a*.b в оболочке, оболочка узнает, что такое a*.b файлы, а затем передает их ls. Теперь вы спрашиваете ls: дайте мне файл с именем nse* буквально . Конечно, такого файла нет.

Вы можете использовать subprocess.check_call(..., shell=True) для запуска команды через оболочку (которая будет выполнять подстановочные знаки перед вызовом команды).

См.:

>>> subprocess.check_call("ls /tmp/foo*".split())
ls: cannot access '/tmp/foo*': No such file or directory
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.7/subprocess.py", line 347, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['ls', '/tmp/foo*']' returned non-zero exit status 2.
>>> subprocess.check_call("ls /tmp/foo*", shell=True)
/tmp/foo.bar  /tmp/foo.c
0

Обратите внимание на номер .split() во втором случае - вся строка передается в качестве аргумента для оболочки.

2 голосов
/ 09 июля 2020

Вы можете сделать:

subprocess.check_call("ls -l /home/user/nse*", shell=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...