выполнение команды оболочки с использованием подпроцесса Python

Почему поведение python subprocess.Popen () является странным при запуске команды оболочки как строки и как списка? когда мы должны передавать команду оболочки как строку и как список?

>>> import subprocess
>>> p = subprocess.Popen('du -sh *', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
>>> stdout, _ = p.communicate()
>>> print stdout[:1000]
244M    bin
3.1M    bmps
14M     buildweb
10M     contrib
4.0M    gobuild
168K    gobuild-starter-kit
468K    gobuild-test
3.6M    lib
46M     machines
1.4M    machineweb
75M     microservices
1.4M    monthly_maintenance
20K     perforce
9.1M    scheduler
196K    service
2.5M    statusweb
516K    storage
228K    symindex
7.2M    webapps

>>> p = subprocess.Popen('du -sh *'.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
>>> stdout, _ = p.communicate()
>>> print stdout[:1000]
8       ./statusweb/infrastructure/management/commands
12      ./statusweb/infrastructure/management
16      ./statusweb/infrastructure
48      ./statusweb/statusweb/settings
56      ./statusweb/statusweb
164     ./statusweb/dashboard/migrations
8       ./statusweb/dashboard/tests/fixtures
64      ./statusweb/dashboard/tests
12      ./statusweb/dashboard/static/dashboard/img
12      ./statusweb/dashboard/static/dashboard/css
48      ./statusweb/dashboard/static/dashboard/js/status
12      ./statusweb/dashboard/static/dashboard/js/spec
72      ./statusweb/dashboard/static/dashboard/js
100     ./statusweb/dashboard/static/dashboard
104     ./statusweb/dashboard/static
36      ./statusweb/dashboard/templates/dashboard/dust
32      ./statusweb/dashboard/templates/dashboard/emails
88      ./statusweb/dashboard/templates/dashboard
8       ./statusweb/dashboard/templates/admin/dashboard/issue
8       ./statusweb/dashboard/templates/admin/dashboard/maintenance
20      ./statusweb/dashboard/templates/admin/dashboard
28      ./statusweb/dashboard/templates/admin
8       ./statusweb/dashboard/templates/registra

person Murali Mopuru    schedule 05.03.2018    source источник


Ответы (1)


Когда вы передаете список, только первый элемент рассматривается как команда. Остальное рассматривается как аргументы оболочки, используемой для запуска команды. Из документов Python:

В POSIX с shell = True для оболочки по умолчанию используется / bin / sh. Если args является строкой, строка указывает команду, выполняемую через оболочку. Это означает, что строка должна быть отформатирована точно так же, как при вводе в приглашении оболочки. Это включает, например, кавычки или обратную косую черту для экранирования имен файлов с пробелами. Если args представляет собой последовательность, первый элемент определяет командную строку, а любые дополнительные элементы будут обрабатываться как дополнительные аргументы для самой оболочки. То есть Popen делает эквивалент:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

person julius383    schedule 05.03.2018