Pull to refresh

Comments 39

А чем не подошел udev? Он может делать тоже самое.
1) Не хотелось зависимости от udev. Да, вроде как он в ближайшее время никуда пропадать не собирается, но чем меньше зависимостей, тем лучше.
2) Не совсем то же самое. К примеру, я уверен, что настраивать там монтирование по UUID — та ещё морока. К тому же — сервис легче отключить, быстрее время отклика (если понизить интервал между опросами до половины секунды, к примеру). Короче, такой же гибкости, просто используя пару правил, не выйдет.

Получается, что если делать по уму, как минимум вешать какой-то похожий на мой скрипт коллбэком сразу на все storage devices, и уже в нём точно так же по уму разбирать UUID, исключения/правила/прочее… А потом смотришь и думаешь — «С одной стороны — скрипт. С другой стороны — скрипт, приделанный к udev, но с той же функциональностью. И какая тогда разница, что писать?»
1) Мне кажется, что лучше все таки использовать стандартное средство. Unix-way'но.
2) Монтирование по UUID настраивается легко, отключить правило udev так-же просто. Про время отклика вы ошибаетесь, ваш скрипт отработает когда устройство появиться в /dev, а появится оно там тогда, когда отработает udev. Ну и зачем нагружать проц постоянным циклом (хоть он почти ничего и не потребляет).
Опять же имхо, выйдет гораздо гибче. Можно фильтровать не только по uuid, но и по моделям, вендору и тд.
1) Насчёт Unix-way согласен. С другой стороны, даже систем, заменяющих init, оказывается, что-то около 3-4. Так что — принцип есть, а вот применим он, оказывается, не везде =) А так, да, признаю, моя работа заменима udev… С похожим вспомогательным скриптом. С одной стороны, я написал в каком-то смысле велосипед. С другой — он выполняет задачу, имеет некоторые преимущества перед аналогом, ну и, в конце концов, свой, родной ;-)
2) Отключение правила udev подразумевает — отредактировать файл или хотя бы держать его название в памяти. А тут — service pautomount stop. Да и время отклика другое, поскольку демон инициализируется один раз — а скрипт каждый раз, когда запускается. А постоянный цикл — это прочитать один раз содержимое директории и сравнить пару переменных. Не так и трудно =)
3) Трудно представить ситуацию, где понадобится фильтровать по модели/вендору, честно. Если даже label_regex как-то себя оправдывает, то use case для этого… Разве что в мастерской, где ремонтируют флешки и для каждой модели флешки есть свой пакет для восстановления данных через сервисный режим контроллера, по счастливой случайности реализованный и включаемый через USB =)
А постоянный цикл — это прочитать один раз содержимое директории и сравнить пару переменных. Не так и трудно =)

использовали бы как минимум inotify: pyinotify или watchdog(на хабре: линк)
Кстати, подобная функциональность есть в pyuv¹ и PySide/PyQt: оба, конечно, не специализированные решения, как watchdog и, тем более, pyinotify, но о них полезно знать на случай, если понадобится какая‐то ещё их возможность.

¹ привязка Python к libuv, которая, в свою очередь, предоставляет платформонезависимые абстракции для ряда платформо‐специфичных вещей для nodejs.
Да, мне тоже показалось, что использовать для этой задачи udev как-то естественнее. Вот пример реализации автоматического монтирования и отмонтирования (при выдёргивании, безопасно для vfat и ext4) флешек — может кому пригодится.

Файл сохранить в /etc/udev/rules.d/, отредактировав в нём первые две строки (имя юзера и путь монтирования):
99-usb-automount.rules
# Allow user mount/umount (set device owner and use 'owner' option in fstab).
# Create mount point directories for vfat/ext2/ext3/ext4/ntfs partitions.
# Create symlinks using partition label (overwrite duplicates).
# Auto-mount vfat with 'flush' option.
# Auto-mount ext4 with 'sync' option.
# No auto-mount for other filesystems (because there is NO SAFE auto-unmount).
# Auto-unmount vfat/ext2/ext3/ext4/ntfs and cleanup directories/symlinks.

ENV{mount_user}="powerman"
ENV{mount_path}="/mnt"

KERNEL=="sd*", DRIVERS=="usb-storage", ENV{ID_FS_TYPE}!="", \
    OWNER="%E{mount_user}", \
    ENV{mount_point}="usb.%k"

ACTION=="add",    ENV{mount_point}!="", ENV{ID_FS_TYPE}=="vfat", \
    ENV{mount_fs}="vfat", \
    ENV{mount_opts}="flush,owner,umask=007,showexec,quiet"
ACTION=="add",    ENV{mount_point}!="", ENV{ID_FS_TYPE}=="ext2|ext3", \
    ENV{mount_fs}="%E{ID_FS_TYPE}", \
    ENV{mount_opts}="owner"
ACTION=="add",    ENV{mount_point}!="", ENV{ID_FS_TYPE}=="ext4", \
    ENV{mount_fs}="ext4", \
    ENV{mount_opts}="sync,owner"
ACTION=="add",    ENV{mount_point}!="", ENV{ID_FS_TYPE}=="ntfs", \
    ENV{mount_fs}="ntfs-3g", \
    ENV{mount_opts}="owner,umask=007,fmask=111"

ACTION=="add",    ENV{mount_point}!="", \
    RUN+="/bin/mkdir -p %E{mount_path}/%E{mount_point}", \
    RUN+="/bin/sed -i.bak '$a/dev/%k %E{mount_path}/%E{mount_point} %E{mount_fs} %E{mount_opts} 0 0' /etc/fstab"
ACTION=="add",    ENV{mount_point}!="", ENV{ID_FS_TYPE}=="vfat|ext4", \
    RUN+="/usr/bin/sudo -u %E{mount_user} /bin/mount %E{mount_path}/%E{mount_point}", \
    RUN+="/usr/bin/sudo -u %E{mount_user} /usr/bin/env DISPLAY=:0 /usr/bin/notify-send -t 2500 -u normal -i /usr/share/icons/oxygen/48x48/devices/drive-removable-media-usb-pendrive.png 'USB Flash automounted' '%E{mount_point}\n%E{ID_FS_LABEL}'"
ACTION=="remove", ENV{mount_point}!="", \
    RUN+="/bin/umount -l %E{mount_path}/%E{mount_point}", \
    RUN+="/bin/sed -i.bak '/^\/dev\/%k \S\+\/%E{mount_point} /d' /etc/fstab", \
    RUN+="/bin/rmdir %E{mount_path}/%E{mount_point}", \
    RUN+="/usr/bin/sudo -u %E{mount_user} /usr/bin/env DISPLAY=:0 /usr/bin/notify-send -t 1000 -u normal -i /usr/share/icons/oxygen/48x48/devices/drive-removable-media-usb-pendrive.png 'USB Flash disconnected' '%E{mount_point}\n%E{ID_FS_LABEL}'"

ACTION=="add",    ENV{mount_point}!="", ENV{ID_FS_LABEL}!="", \
    RUN+="/bin/ln -nsf %E{mount_point} %E{mount_path}/%E{ID_FS_LABEL}"
ACTION=="remove", ENV{mount_point}!="", ENV{ID_FS_LABEL}!="", \
    RUN+="/bin/rm %E{mount_path}/%E{ID_FS_LABEL}"

1. А Вы, простите, КАК до этого скрипта додумались, какие мануалы читали (ну, кроме man udevadm). У меня как-то не получилось совладать с запуском ppp при вставке 3g-модема… udev никакой отладки не предоставляет…
2. Почему RUN+= а не RUN=?
3. Почему в начале скрипта ENV{mount_user}=«powerman» а в скрипте %E{mount_user}
  1. Какие мануалы, не смешите. Не поймите неправильно, я доку читать люблю, причём много и вдумчиво, но не в ситуации когда нужно сделать одноразовый скрипт на птичьем языке очередной тулзы. Погуглил, нашёл похожий пример реализующий базовую функциональность (условную установку переменных, обращение к переменным, и выполнение команды при подключении/отключении флешки) — для нормального программиста этого более чем достаточно, чтобы написать своё решение просто «по аналогии». Что касается отладки — вывод udevadm monitor -u -p достаточно информативен вроде бы.
  2. Надо полагать, = устанавливает (заменяет) значение, а += добавляет к текущему значению. Я использовал += для того, чтобы можно было проще видеть отдельные команды, отключать/заменять их — т.е. просто для лучшей читабельности скрипта.
  3. Потому, что именно таким образом устанавливались и считывались значения переменных окружения в нагугленном мной примере — есть ли какие-то ещё способы это делать в синтаксисе udev я не вникал.
Хотя нет, вру. Какую-то доку я всё-таки тогда попытался почитать, как минимум помню что читал Writing udev rules — но всё-равно, от примера было больше толку, чем от доки.
По-взрослому надо mount_user не константой забивать, а вычислять, чьи X-ы сейчас запущены и находятся на активном VT.
Не поверите, я тоже об этом думал. Но решил, что чем меньше кода работает внутри udev под root-ом, и чем он проще — тем лучше. И что этот фактор важнее, чем писать излишне универсально и по-взрослому.
Помнится, в каком-то дистрибутиве я видел готовое решение. Правда, оно было гномозависимыми или еще какими-то недостатками обладало, так что я не попытался перенести его и адаптировать для себя.
При запуске внешних скриптов нужно иметь в виду возможные спецсимволы в 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, а это присутствует в скриптах крайне редко. Фильтрация только покажет, что вы не разбираетесь в проблеме.
Пока что — да, используется shell режим. В режиме shell=False списки, если я правильно помню, обязательны. Честно скажу — я пробовал использовать списки. Есть одна проблема… Это неэстетично выглядит =) Если вместо каждой строки в конфиге вбивать список — конфиг становится ещё более нечитаемым =( В ближайшее время собираюсь покопаться в os.popen и аналогах, может, там найдётся что-то, что non-shell и принимает на вход строку, а то, действительно, зря я пока subprocess ограничился. Спасибо!
Вы ищете ответ не в той плоскости. Строка без shell нарушает однородность аргументов функций и требует другого кода для обработки, поэтому вы, скорее всего, ничего не найдёте. А вот преобразование строки в список есть и не ограничивается простым unicode.split() или даже re.split(): посмотрите модуль shlex. os.popen*, кстати, если мне не изменяет память, deprecated.

Правда без shell вы очевидно теряете вещи вроде command1;command2.
>>>однородность аргументов функций
Можно объяснить, что это за зверь?

Кстати, спасибо за shlex! Я раньше про него читал, но потом, когда искал ещё-раз, перепутал его с ast, ну и решил, что ошибся и такого инструмента нет. Теперь вспомнил.

Прикол в том, что если ставить shell=False, то теряется возможность использовать "&", "|", ";", "&&". С одной стороны — затыкается дыра. С другой — нужно на каждую команду, где может использоваться один из спецсимволов, писать скрипт и вызывать уже сам скрипт. Короче, либо удобство, либо безопасность =) Поэтому я и думаю фильтровать label, как единственное место, где есть возможность для атаки со стороны обычного юзера. Конфиг не считаю за возможность атаки, так как владелец конфига — рут, если кто-то изменил конфиг, то это не проблема демона, так как скомпрометирована вся система прав.
Однородность? Ни разу не слышали про consistency? Суть в том, что программист, помня некоторый (неполный) набор функций должен быть способен предсказать, какие аргументы принимают функции из того набора, что он не помнит, и какие возвращают значения. Иначе программисту надо часто заглядывать в документацию и он говорит, что язык — говно.
Не могли бы Вы подкинуть какую-нибудь литературу, где поподробнее описан принцип этой самой однородности?

И всё же — если я решу очищать LABEL от всяких спецсимволов, оставляя только ASCII, при этом оставлю shell=True ради того, чтобы удобно было использовать shell extensions — как это покажет мою некомпетентность и непонимание проблемы? Кстати, label всё равно надо фильтровать. Опыт показывает, что русские символы и пробелы в label («Зарезервировано системой», это камень в твою сторону!) довольно сильно усложняют процесс автомонтирования, привнося необходимость избыточного экранирования. Уж не знаю, как кто-то решает подобные вещи при монтировании через udev =)
Тем, что это не является необходимым. Программисты любят универсальные решения и конструктивную параною. Если вы избавитесь от русского языка в метках, то получите абсолютно бесполезные имена: если там есть русский язык, то 99% метка написана полностью по-русски. Это не универсально. mount'у абсолютно без разницы, какие байты есть в имени каталога; при использовании простых двойных кавычек и переменных окружения проблемы могут возникнуть только с / и дефисоминусом в начале аргумента. Это не конструктивно.

Фильтруя символы, вы показываете свою неспособность придумать универсальное и корректное решение. Советую просто использовать мой вариант экранировки из первого комментария из Python (+ os.path.abspath и замена /) и двойные кавычки в скриптах.

//

А литературу по этому поводу я не знаю (хотя она должна быть). Но при совместной разработке чего-либо крайне сложно избежать ситуации, когда вам говорят, что это надо переделать «because it is inconsistent with (some previously added code)». Так же откройте некоторые холивары на программистскую тему, там будут постоянно швыряться аргументами про отсутствие однородности: этим грешат противники PHP в PHP vs что-то, эти аргументы можно найти в войнах git vs что-то… Короче, читайте тематические интернеты и понимание этой концепции само придёт к вам.
Ну так в любом случае после фильтрации нужно проверять — не остались ли от LABEL рожки да ножки. Собственно, это нужно бы проверять и без фильтрации =) Потом, я пишу решение, которое не должно создавать лишних проблем. Если я оставлю русские и прочие Unicode символы, то есть один нюанс — для того, чтобы из консоли без установленной соответствующей раскладки добраться до папки, в которой нет английских символов, нужно использовать mc или что-то типа того. Моё мнение — нафиг так жить. Я уж лучше сделаю один ключ в конфиге, который включает фильтрацию некорректных символов, и один, который включает фильтрацию не-английских раскладок, ну и включу их по дефолту, чтобы улучшить user experience.

Теперь вопрос — можете провести аналогию между Вашим определением однородности и фильтрованием? Моя функция execute(), которая является деривативом от supbrocess.check_output (который является, ЕМНИП, деривативом от os.popen ;-) ), не должна иметь такие же аргументы — она не в том же модуле, не является заменой, а лишь упрощённым вариантом. Более того, я её использую именно потому, что мне просто легче вбить команду строкой, нежели списком аргументов, ну и получать список из (exit_code, output) после каждого вызова, а не ловить эксепшен только из-за того, что код выхода команды — не 0. Зачем однородность в аргументах, если одна из целей — упрощение аргументов?

Кстати, не совсем понимаю, почему Питон требует именно список аргументов. У Вас случаем нет ссылки на PEP или что-то вроде того, где обсуждается эта деталь? Я не нашёл =(
Можно использовать Tab. Можно даже помочь пользователю, добавив предсказуемый ASCII-only префикс.

Однородность относится к библиотекам языка. Я просто объяснил, почему вы вряд ли что-либо найдёте. Есть, конечно, и исключения: см. unicode.translate и bytes.translate (тут исключение, вероятно, связана с оптимизацией) или интерфейсы для работы с архивами и потоковыми форматами сжатия (тут исключение, вероятно, связано с разными разработчиками).

Относительно списка: а что бы вы предложили? Учтите, что никому не нужно тратить время на парсинг (если я формирую команду от и до, а не беру из конфига, то у меня нет никаких проблем со списками: наоборот, строки были бы неудобны). Также в *nix есть семейство функций exec*. Они принимают списки: либо в виде char**, либо в виде аргументов: знаете int main(int argc, char **argv) (иногда ещё и с char **env)? Python использует execve, которая использует именно char ** для списка аргументов. Так что хотите-не хотите, а в *nix список вам нужен.
Tab не работает в таких случаях. Префикс — это уже обработка label и проверка. К тому же префикс никак не поможет Таб-ом перейти на нужную папку в консоли, если папок с одинаковым префиксом больше одной =) Да и глупо будет выглядеть. Лучше уж сразу тогда монтировать по UUID, если label некрасивый — как у меня сделано в случае, когда label не существует =)

Про библиотеки из C, которые используются как основы для Питоновских библиотек, понятно. Но если уж Питон предоставляет обёртки над функциями из C — можно сделать эти обёртки удобными, как это, собственно, и сделано в большинстве Питоновских библиотек.
Про формировку — тоже понятно, впрочем, можно добавить строчку с " ".join(argument_list), если функция требует строку, делов-то =) Может, мне url для urllib2 удобнее массивом отдавать — удобство формировки аргументов для всех, кто формирует команды от и до, не должно заставлять всех остальных делать так же. Я имею в виду то, что если это было бы единственным аргументом в пользу списков, то списки точно не были бы нужны =)

Насчёт однородности — нашёл os.system. Принимает на вход строку. stdout не выдаёт, правда, как и subprocess.call =( Более того, однородность между теми же check_output и popen тоже неполная — так почему между моей функцией и вышеперечисленными она должна быть полной?

То же разное поведение subprocess.check_output при shell=True и shell=False — это ли не вопиющий пример неоднородности? Вон, человек тоже недоволен — asvetlov.blogspot.com/2011/03/subprocess.html, плюс там пример вообще неадекватного поведения.
И баг есть в багтрекере — bugs.python.org/issue7839. Там тоже это поведение описано.
Собственно, я свою функцию execute() написал, когда с этой фигнёй столкнулся. В скором времени добавлю в неё поддержку shell=False при помощи shlex — будет нормальной =)
Tab не работает в таких случаях.
Да ну? Переходите на zsh, всё работает. В fish тоже всё работает. Даже bash можно настроить, чтобы всё работало. Под «всё» я имею ввиду, что повторное нажатие Tab вызывает циклическое переключение между вариантами автодополнения. Zsh дополнительно позволяет управлять переключением стрелками, что очень помогает (как ни странно, у меня нет русской раскладки и все русские тексты я пишу либо со смартфона (транслитом, но используя ruKeyboard), либо транслитом в Vim). Так что я знаю, о чём говорю.

К тому же префикс никак не поможет Таб-ом перейти на нужную папку в консоли, если папок с одинаковым префиксом больше одной =)
Это целиком и полностью вопрос выбора способа создания префикса.

Про библиотеки из C, которые используются как основы для Питоновских библиотек, понятно. Но если уж Питон предоставляет обёртки над функциями из C — можно сделать эти обёртки удобными, как это, собственно, и сделано в большинстве Питоновских библиотек.
Они удобные. Во‐первых, только shell оперирует сплошной строкой: и exec*, и main(), и вещи вроде sys.argv — это всё списки.

Сплошная строка в main()/sys.argv никому на хрен не сдалась и совершенна неудобна: попытайтесь обработать список файлов, полученный в виде сплошной строки и поймёте, почему. Соответственно нелогично иметь сплошную строку на другом конце: это нарушает принцип «явное лучше неявного»: получается «сплошная строка» → «магия» → «список». Вряд ли вы найдёте здесь много человек, способных полностью описать, как работает «магия» в случае с shell: а ведь там это одна из основополагающих вещей.

Собственно, здесь вы нарушаете сразу два принципа: «явное лучше неявного» и «простое лучше сложного». Это не дело.

Сплошная строка небезопасна, так как проще всех посадить на генерацию списков, чем научить всегда использовать экранирование.

Сплошная строка неудобна для генерации списка аргументов из списка вещей (к примеру, файлов) — из‐за экранирования простым ' '.join(argument_list) не обойдётся.

Список удобен для генерации аргументов от и до, и, чёрт возьми, я ни разу, ни в одной своей программе не хотел использовать shell=True или использовать строку. И, по‐моему, нигде и не использую.

Сплошная строка неэкономична: чтобы её создать вам придётся пройти процесс «генерация аргументов» — «экранирование» — «парсинг строки» — «генерация char ** массива». В случае списка половина пунктов из середины выкидывается.

И ещё, если у вас есть функция со списком, то вы можете взять её и прикрутить наверх функцию со строкой, обратное тоже верно. Так зачем тащить в стандартную библиотеку всякую дрянь? Ruby уже имел проблемы с безопасностью от того, что никто не помнит всю документацию (вспомните, к примеру, $ против \Z).
Конечно, вы не можете сделать язык, на котором все программы будут безопасны. Но вы можете уменьшить нагрузку на программиста, уменьшив пространство выбора, оставив только более безопасные решения. В идеологии языка никогда не было TMTOWTDI.

В Python было бы логичнее сделать Popen с *args в качестве списка, чтобы не отличаться от прочих функций, а никак не принимать на вход строку. И отдельный модуль, который позволяет засунуть в *args запуск $SHELL с заданной строкой.

Насчёт однородности — нашёл os.system.
В модуле os много практически прямых привязок к C’шным функциям. И этот вариант использует оболочку. Кроме того, «The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function.» и «Note that POSIX does not specify the meaning of the return value of the C system() function, so the return value of the Python function is system-dependent

То есть вы нашли deprecated функцию. Не удивительно, что тут не соблюдается условие однородности: такие функции существуют только для обратной совместимости. По‐моему, её не собираются удалять только потому, что из‐за простоты os.system слишком часто используется.

Более того, однородность между теми же check_output и popen тоже неполная — так почему между моей функцией и вышеперечисленными она должна быть полной?
Мне не жалко повторить во второй раз, что однородность должна быть в библиотеках языка, и что она не идеальна. И, кстати, вы не нашли «что-то, что non-shell и принимает на вход строку». Ну и os.popen* тоже deprecated. Более того, в документации на os.system стоит просто рекомендация использовать subprocess. А в документации на os.popen стоит очень заметное розовое предупреждение о том, что popen «Deprecated since version 2.6». Жаловаться на неоднородность deprecated функций имеет не больше смысла, чем жаловаться на то, что человеческий эмбрион не выглядит как человек: такие неоднородности обусловлены историческими причинами.

Замечу, что в Python 3 ситуация иная: там нет ни deprecation warning при os.popen (но есть рекомендация использовать subprocess), ни информации о том, что с subprocess нужен для замены os.popen в первых абзацах документации этого модуля: здесь написано только то, что subprocess — это замена os.system и os.spawn*. os.popen с цифрами, впрочем, нет вообще.

То же разное поведение subprocess.check_output при shell=True и shell=False — это ли не вопиющий пример неоднородности? Вон, человек тоже недоволен — asvetlov.blogspot.com/2011/03/subprocess.html, плюс там пример вообще неадекватного поведения.
Я с ним согласен. Как я сказал выше, я бы вообще зарубил Popen возможность использовать shell, но добавил модуль или функцию в subprocess, которая сформирует список аргументов для Popen так, чтобы вызывался shell со строкой. Ну и Popen('cat', filename, filename2) выглядит лучше, чем Popen(['cat', filename, filename2]). Но всё это не меняет того факта, что функции в subprocess принимают практически одни и те же аргументы.
Кстати, в той issue, что вы привели здесь, есть ссылка на shell-command.readthedocs.org/en/latest/index.html. Если вам нужно использовать оболочку, то этот модуль выглядит весьма интересно (он занимается, в том числе, автоматическим экранированием аргументов).
«label_regex»:"*iPhone*"
Обычно при слове regex ожидают один из диалектов Perl’оподобных регулярок, либо что‐то вроде ERE/BRE. А это обычно называется glob либо более общим pattern (которое также может относится и к regex). Если вы подаёте код Python’овскому re.*, то выражение должно выглядеть как .*iPhone.*. Если это выражение правильно, то поле лучше переименовать.
>>>«comment»:«За правильность регулярки вообще не ручаюсь»
Я просто очень редко сталкиваюсь с регулярными выражениями, уже подзабыл, как и что конкретно в Питоне. Естественно, что ожидается Perl-like регулярное выражение =) Сейчас добавлю, спасибо!
К черту Поттеринга, я напишу свой systemd с питоном и скриптами!
Как будто systemd — это что-то плохое. Само его существование никого не заставляет на него переходить, если не ошибаюсь, даже в новом Дебиане есть возможность его безболезненно отключить. Да и, насколько понимаю, его не зря выбрали новой init system:
The Debian Technical Committee voted to make systemd the default system management daemon for Linux in the «jessie» release.
lists.debian.org/debian-ctte/2014/02/msg00405.html — думаю в ближайшее время прочитать эту дискуссию сначала. Всё же ну очень интересно — почему =)
Само его существование никого не заставляет на него переходить.
Только теоретически. По факту, вам придётся отказаться от популярных дистрибутивов, если вы не сторонник systemd.
Да и, насколько понимаю, его не зря выбрали новой init system.
По поводу адекватности этого выбора ведутся жаркие баталии (на ЛОРе — при выходе любой новости про systemd). Даже на хабре не так давно статья была: habrahabr.ru/post/223351/ если у вас есть желание подискутировать на эту тему, то я рекомендую делать это в том топике.
UFO just landed and posted this here
Cхемой кабеля для зарядки ipod'а не поделитесь?
pinouts.ru/PortableDevices/ipod_pinout.shtml
Это для Nano:
>>>To charge iPod Nano, USB D+ & D- should be tied together and then connected to a 10K ohm resistor, and the other side of this resistors then needs to be connected to 5v power.
То есть — от источника питания отходит два провода — земля и питание, на кабеле со стороны айпода пины USB D+ и D- закорачиваются, и 10К резистором подтягиваются к питанию. У меня работало с iPod Nano 6G.
Со всеми остальными устройствами от Apple — только выставлять напряжения резисторными делителями. Я просто беру два маленьких потенциометра, которые регулируются отвёрткой, подсоединяю у обоих один крайний контакт к земле, один к питанию, а центральные идут на D- и D+. Естественно, для начальной регулировки нужен вольтметр — зато не нужно искать какие-то резисторы по 77к =)
Собственно, у меня в черновиках есть уже одна статья насчёт зарядок, Apple-овских и не очень, да вот только Хабр решил, что хаб DIY — это для меня роскошь =) Вообще, странно, почему DIY — непрофильный хаб. Один из самых интересных и популярных, если посмотреть.
UFO just landed and posted this here
Да уж, раз в секунду проверять наличие файла в ФС… Конечно загрузка процессора будет ничтожна, но всё-таки это — неправильно!
Совершенно не вижу смысла в этом велосипеде.
Для организации автоматических бэкапов по UUID ФС на флешке можно простой скрипт на баше записать, который будет вызываться udev'ом.
Но я бы так не делал. Надежнее вручную запустить — вдруг какие ошибки возникнут? Да и непонятно, как сигнализировать об окончании процесса, если он в фоне идет — музыку сыграть? А вдруг ты резервирование ночью делаешь, когда все родные спят? И тут на всю квартиру «тадам!».
1) Считайте это простым скриптом на Bash, только на Python =) Я не люблю Bash, честно. Причины заслуживают отдельной статьи — и включают в себя определённые неудобства в использовании, возможно, правда, только лично для меня, куча телодвижений для нормальной обработки имён файлов в 100& случаев. Тот же JSON на Баше разбирать — довольно неочевидная штука. Да, BASH определённо собрал бы больше плюсов, но для этой цели Python лучше. К тому же мне лично не нравится каждый раз редактировать правила в udev =)

2) Голосовое/звуковое оповещение — одна из тем, которую я собираюсь реализовать в ближайшее время, и, естественно, периоды оповещения — актуальная тема. Я уже один раз решал это с помощью скрипта-обёртки над Festival, правда, написан он по-нубски и сейчас особой ценности не представляет =) Если вкратце — для festival были созданы файлы, в каждом из которых был короткий сценарий с фразой. festival для обработки таких файлов запускается с опцией -b file (--batch). Мой скрипт становился вместо festival, принимал эту опцию и проверял текущее время, ну и вызывал festival, если время позволяло =) Но, думаю, Насчёт ошибок — тоже решается сигнализацией, которая, к слову, может быть не только звуковой.
В ближайшем времени буду искать простое решение, вроде демона, который бы централизованно управлял бы всеми оповещениями на сервере и пропускал/не пропускал бы их в зависимости от времени/важности/типа/чего-нибудь ещё. Не найду — напишу сам =)
Sign up to leave a comment.

Articles