Почему действительно подобрабатывает. Popen () с shell=True работают по-другому над Linux по сравнению с Windows?

Если Вы уверены, что только JavaScript будет использовать JSON, я предпочитаю передавать объекты Javascript Date непосредственно.

ctime() метод на datetime объекты возвратят строку, которую может понять объект Даты JavaScript.

import datetime
date = datetime.datetime.today()
json = '{"mydate":new Date("%s")}' % date.ctime()

JavaScript будет счастливо использовать это в качестве литерала объектов, и у Вас есть свой объект Даты, созданный прямо в.

20
задан Ben Hoyt 10 August 2009 в 04:39
поделиться

2 ответа

В чем разница между этими двумя операторами

Первый возвращает отфильтрованную последовательность исходного / полного исходного объекта; второй по-прежнему выполняет фильтр, но возвращает последовательность анонимного типа с только этими тремя свойствами.

Есть ли в этих операторах какие-либо проблемы, связанные с производительностью

Производительность зависит от серверной части. Если это LINQ-to-Objects, то с new {...} вы создаете дополнительные объекты (анонимные типы) для каждой записи, так что могут возникнуть очень небольшие накладные расходы. Однако, если это LINQ-to-SQL и т. Д. (Серверная часть базы данных), то это может быть огромным преимуществом . Конструктор запросов проверит, какие столбцы необходимы, и выберет только три из вашего анонимного типа; (В Windows 95/98 для фактического запуска команды используется промежуточная программа w9xpopen .)

Таким образом, странная реализация на самом деле представляет собой UNIX , которая выполняет следующие действия (где каждый пробел разделяет другой аргумент):

/bin/sh -c gcc --version

Похоже, что правильная реализация (по крайней мере, в Linux) будет:

/bin/sh -c "gcc --version" gcc --version

Поскольку это установит командную строку из указанных в кавычках параметров и успешно передаст другие параметры.

Из раздела справочной страницы sh для -c :

Считывать команды из операнда command_string, а не из стандартного ввода. Специальный параметр 0 будет установлен из операнда command_name, а позиционные параметры ($ 1, $ 2 и т. Д.) Будут установлены из оставшихся операндов аргументов.

Этот патч, кажется, довольно просто делает фокус:

--- subprocess.py.orig  2009-04-19 04:43:42.000000000 +0200
+++ subprocess.py       2009-08-10 13:08:48.000000000 +0200
@@ -990,7 +990,7 @@
                 args = list(args)

             if shell:
-                args = ["/bin/sh", "-c"] + args
+                args = ["/bin/sh", "-c"] + [" ".join(args)] + args

             if executable is None:
                 executable = args[0]
15
ответ дан 30 November 2019 в 01:11
поделиться

Из источника subprocess.py:

В UNIX, с shell = True: если args является строкой, она указывает командная строка для выполнения через оболочку. Если args - последовательность, первый элемент определяет командную строку и любые дополнительные элементы будут рассматриваться как дополнительные аргументы оболочки.

В Windows: класс Popen использует CreateProcess () для выполнения дочернего элемента программа, которая работает со строками. Если args - последовательность, она будет преобразован в строку с помощью метода list2cmdline. Обратите внимание, что не все приложения MS Windows интерпретируют командную строку одинаково способ: list2cmdline предназначен для приложений, использующих тот же правил как среда выполнения MS C.

Это не объясняет почему, просто поясняет, что вы видите ожидаемое поведение.

«Почему», вероятно, заключается в том, что в UNIX-подобных системах аргументы команд фактически передаются в приложения (использующие семейство вызовов exec * ) в виде массива строк. Другими словами, вызывающий процесс решает, что входит в КАЖДЫЙ аргумент командной строки. В то время как, когда вы говорите ему использовать оболочку, вызывающий процесс фактически получает возможность передать оболочке только один аргумент командной строки: всю командную строку, которую вы хотите выполнить, имя исполняемого файла и аргументы в виде одной строки.

Но в Windows вся командная строка (согласно приведенной выше документации) передается дочернему процессу как одна строка. Если вы посмотрите документацию по API CreateProcess , то заметите, что он ожидает, что все аргументы командной строки будут объединены в большую строку (отсюда и вызов list2cmdline ).

Плюс тот факт, что в UNIX-подобных системах на самом деле является оболочкой, которая может делать полезные вещи, поэтому я подозреваю, что другая причина разницы в том, что в Windows shell = Истинный ничего не делает, поэтому он работает так, как вы видите. Единственный способ заставить две системы действовать одинаково - это просто отбросить все аргументы командной строки, когда shell = True в Windows.

вы заметите, что он ожидает, что все аргументы командной строки будут объединены в одну большую строку (отсюда и вызов list2cmdline ).

Кроме того, в UNIX-подобных системах действительно есть - это оболочка, которая может делать полезные вещи, поэтому я подозреваю, что другая причина разницы заключается в том, что в Windows shell = True ничего не делает, поэтому она работает так вы видите. Единственный способ заставить обе системы работать одинаково - это просто отбросить все аргументы командной строки, когда shell = True в Windows.

вы заметите, что он ожидает, что все аргументы командной строки будут объединены в одну большую строку (отсюда и вызов list2cmdline ).

Кроме того, в UNIX-подобных системах действительно есть - это оболочка, которая может делать полезные вещи, поэтому я подозреваю, что другая причина разницы заключается в том, что в Windows shell = True ничего не делает, поэтому она работает так вы видите. Единственный способ заставить обе системы работать одинаково - это просто отбросить все аргументы командной строки, когда shell = True в Windows.

shell = True ничего не делает, поэтому он работает так, как вы видите. Единственный способ заставить две системы действовать одинаково - это просто отбросить все аргументы командной строки, когда shell = True в Windows.

shell = True ничего не делает, поэтому он работает так, как вы видите. Единственный способ заставить две системы действовать одинаково - это просто отбросить все аргументы командной строки, когда shell = True в Windows.

5
ответ дан 30 November 2019 в 01:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: