Однородность? Ни разу не слышали про consistency? Суть в том, что программист, помня некоторый (неполный) набор функций должен быть способен предсказать, какие аргументы принимают функции из того набора, что он не помнит, и какие возвращают значения. Иначе программисту надо часто заглядывать в документацию и он говорит, что язык — говно.
Кстати, подобная функциональность есть в pyuv¹ и PySide/PyQt: оба, конечно, не специализированные решения, как watchdog и, тем более, pyinotify, но о них полезно знать на случай, если понадобится какая‐то ещё их возможность.
¹ привязка Python к libuv, которая, в свою очередь, предоставляет платформонезависимые абстракции для ряда платформо‐специфичных вещей для nodejs.
Вы ищете ответ не в той плоскости. Строка без shell нарушает однородность аргументов функций и требует другого кода для обработки, поэтому вы, скорее всего, ничего не найдёте. А вот преобразование строки в список есть и не ограничивается простым unicode.split() или даже re.split(): посмотрите модуль shlex. os.popen*, кстати, если мне не изменяет память, deprecated.
Правда без shell вы очевидно теряете вещи вроде command1;command2.
Обычно при слове regex ожидают один из диалектов Perl’оподобных регулярок, либо что‐то вроде ERE/BRE. А это обычно называется glob либо более общим pattern (которое также может относится и к regex). Если вы подаёте код Python’овскому re.*, то выражение должно выглядеть как .*iPhone.*. Если это выражение правильно, то поле лучше переименовать.
При запуске внешних скриптов нужно иметь в виду возможные спецсимволы в partition label, типа случайно попавших туда "&&rm -rf /" (сработает при запуске внешнего скрипта) и "../../etc/" (может смонтировать раздел вместо "/etc") ;-) Вопрос — какие спецсимволы нужно фильтровать для полной защиты этой дыры? На ум сразу приходят "&", "/" и ";", но может быть больше.
Почему бы не воспользоваться либо списками (при использовании списков в Python запуск внешних программ обходится без shell), либо экранированием строки (правда я знаю всего один способ экранирования на Python: замените её на "$_ARGUMENT_0001" и предоставьте соответствующую переменную окружения). При правильном подходе единственное, что надо будет учитывать — это /, который надо на что‐то заменить (можете проверить как это сделано системой в /dev/disk/by-label).
Внутри скриптов тоже придётся это учитывать, поэтому перед тем, как запустить команду, сконструируйте полный путь и не забудьте про кавычки (;rm -rf / не доставит вам никаких проблем в команде mount $MOUNTPOINT $DEVICE, кроме того, что из‐за пробелов mount получит в аргументах /mnt/;rm, -rf, / и /dev/…).
Полный путь нужен, чтобы избавиться от потенциальных проблем с - в начале имени. Для того, чтобы при наличии в переменной ;rm -rf /, его запустить вам нужен eval либо что‐то эквивалентное вроде запуска sh -c, а это присутствует в скриптах крайне редко. Фильтрация только покажет, что вы не разбираетесь в проблеме.
В Vim своя реализация blowfish, аудит которой практически не проводился, и небезопасный zip по-умолчанию. Кроме того есть какие-то претензии к коду этой реализации и безопасности самого алгоритма, из-за которой обсуждается, как лучше отговорить (запретить, сделать невозможным) пользователей neovim от использования этого шифрования. За претензии к коду я не поручусь, но принятие нового шифрования при минимальном аудите видел. Учитывая «популярность» шифрования Vim можно утверждать, что его никто всерьёз не ломал. Issue с более детальным обсуждением: github.com/neovim/neovim/issues/694.
Это не мешает обсуждать добавление дополнительных входов: различная гадость, срабатывающая только от акселерометра не поможет, если коробку перехватят у инкассаторов, а плёнка сама по себе не поможет, если есть время для работы (при перехвате у инкассаторов спохватятся намного быстрее).
Совершенно не того же. eval с блоком в Perl есть и используется вместо try/catch и абсолютно безопасен. Опасен только eval со строкой. В вашем примере, что бы не находилось в переменной $file будет вызван require с одним аргументом и больше ничего.
Под «живыми» могут пониматься и, так сказать, «политически активные». То есть будут смотреть, сколько криков будет, и каких. Этого в логах так просто не найдёшь, хотя что‐то можно и прикинуть (в конце концов, не первый раз они что‐то закрывают). Посмотрели в логах, прикинули что шуму будет не слишком много и отключили.
Или ничего не смотрели и просто отключили. Могут позволить.
Разница в том, что на шелле у нас 3, допустим, маленьких скрипта, которые принимают 1-2 параметра и документируют сами себя через имена параметров (запускаем без параметров и получаем usage), а в случае других скриптовых языков будет один большой скрипт с десятком параметров, которые нужно выдумать, описать, реализовать их обработку.
Я обычно использую --help для usage (если неохота писать полноценную документацию: тогда --help будет и не для usage) и принцип garbage in — garbage out для запуска без параметров (т.е. если нет --help то скрипт может отработать как угодно, если ему требуются параметры (и как надо, если не требуются)).
Причина: --help более универсален. Если вы запустите большинство программ с --help вам покажут справку. Если нет — то как повезёт: cp --help и dd --help оба кажут справку, тогда как только cp показывает справку без --help. То же самое относится к редакторам, интерпретаторам (кроме стандартных sed и awk), различным GUI программам — все они показывают справку с --help и запускаются без аргументов. Есть и исключения, но их мало: намного меньше, чем программ с --help, но без справки при отсутствии параметров.
Обычно ошибка — это непредусмотренный сценарий, который должен был быть предусмотрен (неверный код, написанный программистом), а исключение — объект, при «выбрасывании» которого разворачивается стёк.
Если говорят об «ошибках против исключений» (с предыдущим определением ошибки и исключения сравнивать нельзя), то под ошибками обычно понимается специальное возвращаемое значение (не вызывающее раскручивание стёка), а под исключениями понимается всё то же. О (не)предусмотренности сценария здесь речи не идёт вообще.
Ни разу не слышал, чтобы в данном контексте исключение было «чем‐то из ряда вон выходящим». Это просто возможность языка, использоние которой для разных целей тут и обсуждают.
Я бы скорее сказал, что «жители этого топика» не увидели в ваших сообщениях такого предложения (я его, кстати, там тоже не увидел). Вот вы в первом сообщении сказали про QA отдел, но не сказали про обработку исключений ни‐че‐го. А ведь вывод информации об ошибке в удобном для пользователя и отдела QA виде — это тоже вариант обработки.
Надо просто лучше раскрывать мысль в комментариях. Думаю не ошибусь, если скажу, что backtrace из второго комментария прежде всего ассоциируется с командной строкой. В крайнем случае — с каким‐то скрытым от пользователя логом. В любом случае — с чем‐то, с чем обычному пользователю неудобно работать.
Есть множество исключений, не говорящих об ошибке в программе, но которые нужно обрабатывать и которые требуют сложных обработчиков. Если ваша программа должна работать в условиях нехватки памяти, то обработчик соответствующего исключения может быть довольно сложен: ему надо где‐то найти память, освободить её (желательно не дав занять тому процессу, что захватил остальную память) и продолжить прерванный процесс. Есть ещё исключения, связанные с ФС: сообщение об отсутствии привелегий для чтения нужного файла или отсутствие самого файла обычно лучше донести всё же до администратора пользователя, а не до QA отдела (если только это не ошибка установщика).
И не надо называть исключения ошибками (хотя это не вы начали).
А что насчёт Github? И, кстати, как получается версия для Python? Очень похоже на какой‐то автоматический конвертер.
Ссылка на Python версию сейчас нерабочая (“The requested URL /download/emt3.3-python.zip was not found on this server.”). И ещё, никогда не используйте файловый менеджер MacOS X для создания архивов. Он добавляет мусор:
Каталог __MACOSX не нужен никому, кроме тех, кто пользуется для распаковки тем же, чем вы пользовались для запаковки. Да и у пользователей MacOS X без него всё прекрасно работает.
А я думал, это специфика zsh. Оказывается, bash просто не работает с таким перенаправлением без указания команды (конструкция SomeCommand <(<<< "some string") является вполне рабочей в zsh, но не в bash).
Я бы не назвал её полезной. Сокрытие файлов я отключаю везде (кроме shell glob) и вот почему:
1. Мне не хочется внезапно узнать, что в том месте, в которое я что-то скопировал/заархивировал/..., оказался лишний мусор.
2. Ещё меньше мне хочется узнать, что я пропустил какой-то нужный файл, потому что ls его не показывает, а оболочка по-умолчанию эти файлы не добавляет при раскрытии glob.
3. Гораздо проще посмотреть все файлы, а не гадать, почему какой-нибудь rmdir отказался работать.
4. В домашнем каталоге огромная куча нужных файлов начинается с точки. Ещё есть .hg*/.git* (не только каталоги). И мне всё это надо редактировать.
Поэтому я считаю, что скрытых файлов не должно быть вообще. Shell globbing здесь стоит отдельно: чтобы пользовательские настройки ничего не сломали надо в начале каждой функции писать «emulate -L zsh». Что закономерно приводит к сбросу настроек для globbing. Так что проще привыкнуть, чем писать в два раза больше одинаковых строк в каждой функции.
xrange не устарел, просто его переименовали. Удалён был именно range. Для бо́льшей переносимости лучше просто всегда писать range. А для скорости — добавлять в начале модуля
try:
from __builtin__ import xrange as range
except ImportError:
pass
¹ привязка Python к libuv, которая, в свою очередь, предоставляет платформонезависимые абстракции для ряда платформо‐специфичных вещей для nodejs.
Правда без shell вы очевидно теряете вещи вроде command1;command2.
regex
ожидают один из диалектов Perl’оподобных регулярок, либо что‐то вроде ERE/BRE. А это обычно называетсяglob
либо более общимpattern
(которое также может относится и кregex
). Если вы подаёте код Python’овскомуre.*
, то выражение должно выглядеть как.*iPhone.*
. Если это выражение правильно, то поле лучше переименовать."$_ARGUMENT_0001"
и предоставьте соответствующую переменную окружения). При правильном подходе единственное, что надо будет учитывать — это/
, который надо на что‐то заменить (можете проверить как это сделано системой в /dev/disk/by-label).Внутри скриптов тоже придётся это учитывать, поэтому перед тем, как запустить команду, сконструируйте полный путь и не забудьте про кавычки (
;rm -rf /
не доставит вам никаких проблем в командеmount $MOUNTPOINT $DEVICE
, кроме того, что из‐за пробеловmount
получит в аргументах/mnt/;rm
,-rf
,/
и/dev/…
).Полный путь нужен, чтобы избавиться от потенциальных проблем с
-
в начале имени. Для того, чтобы при наличии в переменной;rm -rf /
, его запустить вам нуженeval
либо что‐то эквивалентное вроде запускаsh -c
, а это присутствует в скриптах крайне редко. Фильтрация только покажет, что вы не разбираетесь в проблеме.То есть банкомат‐то утащат. Но пока его тащат банкноты зальёт этой гадостью.
eval
с блоком в Perl есть и используется вместо try/catch и абсолютно безопасен. Опасен толькоeval
со строкой. В вашем примере, что бы не находилось в переменной$file
будет вызванrequire
с одним аргументом и больше ничего.Или ничего не смотрели и просто отключили. Могут позволить.
Причина: --help более универсален. Если вы запустите большинство программ с --help вам покажут справку. Если нет — то как повезёт:
cp --help
иdd --help
оба кажут справку, тогда как толькоcp
показывает справку без--help
. То же самое относится к редакторам, интерпретаторам (кроме стандартных sed и awk), различным GUI программам — все они показывают справку с --help и запускаются без аргументов. Есть и исключения, но их мало: намного меньше, чем программ с --help, но без справки при отсутствии параметров.Если говорят об «ошибках против исключений» (с предыдущим определением ошибки и исключения сравнивать нельзя), то под ошибками обычно понимается специальное возвращаемое значение (не вызывающее раскручивание стёка), а под исключениями понимается всё то же. О (не)предусмотренности сценария здесь речи не идёт вообще.
Ни разу не слышал, чтобы в данном контексте исключение было «чем‐то из ряда вон выходящим». Это просто возможность языка, использоние которой для разных целей тут и обсуждают.
Надо просто лучше раскрывать мысль в комментариях. Думаю не ошибусь, если скажу, что backtrace из второго комментария прежде всего ассоциируется с командной строкой. В крайнем случае — с каким‐то скрытым от пользователя логом. В любом случае — с чем‐то, с чем обычному пользователю неудобно работать.
И не надо называть исключения ошибками (хотя это не вы начали).
Ссылка на Python версию сейчас нерабочая (“The requested URL /download/emt3.3-python.zip was not found on this server.”). И ещё, никогда не используйте файловый менеджер MacOS X для создания архивов. Он добавляет мусор:
Каталог __MACOSX не нужен никому, кроме тех, кто пользуется для распаковки тем же, чем вы пользовались для запаковки. Да и у пользователей MacOS X без него всё прекрасно работает.
SomeCommand <(<<< "some string")
является вполне рабочей в zsh, но не в bash).1. Мне не хочется внезапно узнать, что в том месте, в которое я что-то скопировал/заархивировал/..., оказался лишний мусор.
2. Ещё меньше мне хочется узнать, что я пропустил какой-то нужный файл, потому что ls его не показывает, а оболочка по-умолчанию эти файлы не добавляет при раскрытии glob.
3. Гораздо проще посмотреть все файлы, а не гадать, почему какой-нибудь rmdir отказался работать.
4. В домашнем каталоге огромная куча нужных файлов начинается с точки. Ещё есть .hg*/.git* (не только каталоги). И мне всё это надо редактировать.
Поэтому я считаю, что скрытых файлов не должно быть вообще. Shell globbing здесь стоит отдельно: чтобы пользовательские настройки ничего не сломали надо в начале каждой функции писать «emulate -L zsh». Что закономерно приводит к сбросу настроек для globbing. Так что проще привыкнуть, чем писать в два раза больше одинаковых строк в каждой функции.
range
. А для скорости — добавлять в начале модуля