Из источника subprocess.py:
В UNIX с оболочкой = True: если args - это строка, она указывает строку команд, выполняемую через оболочку. Если args - это последовательность, первый элемент указывает командную строку, а любые дополнительные элементы будут рассматриваться как дополнительные аргументы оболочки.
В Windows: класс Popen использует CreateProcess () для выполнения дочерней программы, которая работает на строках. Если args - это последовательность, она будет преобразована в строку, используя метод list2cmdline. Обратите внимание, что не все приложения MS Windows интерпретируют командную строку так же: List2cmdline предназначена для приложений, использующих те же правила, что и среда выполнения MS C.
blockquote>Это не отвечает на вопрос, просто объясняет, что вы видите ожидаемое поведение.
Вероятно, что «почему» в UNIX-подобных системах аргументы команды фактически передаются приложениям (с использованием семейства вызовов
exec*
) в качестве массив строк. Другими словами, вызывающий процесс решает, что входит в аргумент командной строки EACH. Если вы говорите ему использовать оболочку, вызывающий процесс на самом деле получает возможность передать только один аргумент командной строки для выполняемой оболочки: всю командную строку, которую вы хотите исполнить, исполняемое имя и аргументы, как одна строка.Но в Windows вся командная строка (согласно приведенной выше документации) передается в виде отдельной строки дочернему процессу. Если вы посмотрите на документацию API CreateProcess , вы заметите, что он ожидает, что все аргументы командной строки будут объединены вместе в большую строку (следовательно, вызов
list2cmdline
).Плюс есть тот факт, что в UNIX-подобных системах на самом деле есть оболочка, которая может делать полезные вещи, поэтому я подозреваю, что другая причина разницы в том, что в Windows,
shell=True
ничего не делает, поэтому он работает так, как вы видите. Единственный способ заставить эти две системы действовать одинаково - это просто отказаться от всех аргументов командной строки, когдаshell=True
в Windows.
libc.so
представляет собой скрипт компоновщика , небольшой текстовый файл, который выглядит следующим образом (строки, обернутые здесь для удобства чтения):
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf64-x86-64)
GROUP (
/lib/x86_64-linux-gnu/libc.so.6
/usr/lib/x86_64-linux-gnu/libc_nonshared.a
AS_NEEDED ( /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 )
)
Он инструктирует редактор ссылок ([112 ], который вызывается при компоновке во время сборки, т. е. не в динамическом компоновщике, для поиска символов сначала в libc.so.6
, общем объекте, затем в libc_nonshared.a
, если он не может его найти, и, наконец, в динамическом загрузчике, [ 115]). Это используется для реализации определенных функций, например, в более новых версиях glibc, функции, чувствительной к вызывающему абоненту pthread_atfork
(которая должна быть связана статически, поэтому она помещена в libc_nonshared.a
, а не в libc.so.6
). Сценарий компоновщика обычно вызывается неявно командами gcc
или g++
, но иногда вы видите командные строки, содержащие -lc
, и те, которые выбирают скрипт libc.so
(при динамическом связывании).
Сценарий компоновщика используется только во время сборки. Если ваше изображение содержит библиотеки разработки, такие как libsqlite3-dev
, необходимо включить libc6-dev
(или как называется пакет, предоставляющий скрипт компоновщика libc.so
), поскольку libsqlite3-dev
не может использоваться для связывания новых программ и общих объектов без glibc.