Как стать автором
Обновить

Комментарии 95

НЛО прилетело и опубликовало эту надпись здесь
Давайте примеры команды, посмотрим.
Я вообще надеялся в статье увидеть примеры того, как в «стандартных» шеллах всё плохо и как в xonsh всё это исправляет. Цикл — слишком слабенький пример. Пока что то, что Вы описали, больше похоже на сублимацию NIH-синдрома.
НЛО прилетело и опубликовало эту надпись здесь
как бы такая себе задача для шелл-скриптинга, но уверен, что ее можно решить однострочником, возможно привлекая внешние утилиты (типа jq/yq).
На пайтоне тоже решаться должно достаточно легко, но может не в одну строчку — и самое главное, что там с зависимостями? Не придется ли ставить что-то из доп. модулей?
Повершелла не знаю, но за лёгкую работу с XML и датами ему зачёт. А вот считать логику трудно. Например, неясно, создаётся ли файл .new если он выходит идентичным оригиналу.
В линуксах я обычно делаю что-то такое:
gawk -F\" '
BEGINFILE {
  of=FILENAME ".new";
  changed=0
}
/yml_catalog date/ && $2>2015 {
  "date +\"%F %R\" -d \"" $2 " 3 years\"" | getline $2;
  changed=1
}
{
  print>of
}
ENDFILE {
  if(!changed)
    system("unlink " of);
  close(of)
}' *.xml

Плюсы: обработка файлов любого размера с минимум затрат памяти, можно уловить логику даже не знаю awk.
Минусы: xml не валидируется, xml должен быть отформатирован как в примере.
Скорость работы: 25мб/сек на моём некропк.
Да, кстати, очень вряд ли, что приведенный выше ПаверШелл сниппет будет давить больше, чем 25МБ/сек, т.к. там используется пайпинг.

challenge accepted!


for i in *.xml; do DATE=$(xmlstarlet sel -t -m /yml_catalog -v @date $i); [ "$(date +%s -d"$DATE")" -gt "$(date +%s -d2015-01-01)" ] && xmlstarlet ed -u /yml_catalog/@date -v "$(date -d"$DATE 3 years" "+%F %H-%M")" $i > $i.new; done
Круто! Цикл for и имена файлов с пробелами.

Ну можно на


ls -1 | while read i; do

заменить, там по ходу задачи уже подстроить можно, главное не забывать про кавычки :)

Цикл for легко заменить на вызов xargs или find. -name

кстати bash без проблем имена с пробелами переваривает:


$ touch 1.xml 2.xml '3 4.xml'
$ for i in *.xml; do echo "-$i-"; done
-1.xml-
-2.xml-
-3 4.xml-

Тоже самое для bash:


for i in $(egrep -l 'yml_catalog date="201[5-8]'  *.xml); do   let j=( $(grep date $i | awk -F\" '{print $2}' |awk -F"-" '{print $1}') + 3 );   sed -e "s/yml_catalog date=\"201[5-8]/yml_catalog date=\"${j}/g" $i > ${i}.new ; done
не, не очень… представляю вашему вниманию ";", ":", "\"
Я вам завидую, если вы такое в powershell вбиваете не глядя как однострочник, который еще и без ошибок выполняется и делает то, что было задумано :)
С моей точки зрения это как раз скрипт, просто записанный зачем-то в одну строчку.
Единоразовую задачу я бы сделал в 4 прохода, подставляя каждый раз другой год, неправильным однострочником вида
for f in *.xml; do sed -e 's/^<yml_catalog date="2018-/<yml_catalog date="2021-/' $f > $f.new; done

и забыл.

Если у вас там 29 февраля где-то было, то оно бы вам о себе потом напомнило.

А решение на PowerShell выше, по-Вашему, корректно отработает?
Я думаю, что проблема в постановке задачи, т.к. мы не знаем с какой целью делаем +3 года (можно придумать минимум три способа обработки ситуации 29 февраля).
Основная особенность xonsh в том, что он «магически» угадывает что вы ввели — комманду питона или шелла, и это работает вполне хорошо.

То бишь это Punto Switcher… для боевого оборудования, в котором ТЕОРЕТИЧЕСКИ (!!!) (УТРИРОВАННО И НЕРЕАЛЬНО (!!!)) может сложиться ситуация, при которой моя пайтон-функция rm с аргументами -rf / может восприняться как вызов шелла? Punto Switcher, который может что-то убить? R u kiddin me? Нужно быть самоубийцей, чтобы использовать какую-то динамическую undefinedbehavior-неустойчивую систему без тестирования и дебага на реальных данных!

Годами пытаются закопать незакапываемый шелл… всё тщетно. Годами на хабрах постят знакомства с zsh и IPython в качестве замены якобы неудобного и неприятного стандарта, но IMHO удобнее баша ничего нет и не будет.
Ув. минусующий, я по первому гугол-запросу xonsh deleted нашёл github-issue xonsh-репы с названием «rm -rf *; /foo» deletes /foo. Объясни же мне, в чём я неправ? Или тебе нравится использовать своё железо и данные в качестве «подопытного кролика»? Ну поздравляю, у тебя стальные яйца.
Основная особенность xonsh в том, что он «магически» угадывает что вы ввели
То бишь это Punto Switcher…
Думаю, тут неспроста слово «магически» взято в кавычке: ничего xonsh не угадывает, а различие между вызовом внешних команд и питоновским кодом однозначно детерминировано грамматикой скриптового языка.

Может сложиться ситуация, при которой моя пайтон-функция rm с аргументами -rf / может восприняться как вызов шелла?
Конкретно такая ситуация сложиться не может. Ваш пример с rm -rf *; /foo всё же несколько про другое.
А что с производительностью? Мне тут сказали, что некоторое время назад все было очень плохо.

Бегло посмотрел документацию, сильно смутило в faq
«computing branch names and colors (i.e. if the branch is dirty or not), can be a pretty slow operation. This is bad news because xonsh can try to compute these each time it formats the $PROMPT»
То есть я правильно понимаю, что он не может в многопоточность?
Да вот непонятно как её измерять, визуально всё работает шустро даже на моих убогих ноутах.
Что подразумевается под «не может многопоточность»?

Думаю, что тут дело не в оболочке, а в том, что для проверки того, грязная ветка или нет, надо каждый раз запускать git, который будет оббегать дерево каталогов. Это в любом случае будет очень накладно.

Все эти 'убийцы шелла' обладают фундаментальным недостатком которого нет у шелла: шелл есть везде, от роутера и умного чайника до распределенного кластера. Вся статья, по сути, набор костылей с целью прикрутить очередного убийцу шелла к системе в которой уже есть шелл. Да, шелл неудобен, он устарел. Но в мире уже имеются сотни миллионов строк написанных на нем, которые прежде чем переписывать на что-то новое, надо запускать и поддерживать. Так что вы убиваете его не с того конца.
Плюсую.
А есть ещё одна проблема — он лучше всех оттестирован и неоф-документирован, и большинство проблем уже решено и решения замечательным образом лежат на стэковерфлоу и подобных ему. И нормальные люди считают это не проблемой, а отсутствием оной. KISS!
Здесь все не так хорошо на самом деле. Проблемы есть и они огромные. Я на шелле пишу уже наверно лет 10 и со временем пришел к мысли что если шелл скрипт разрастается больше чем на 100-300 строк, то это офигенный такой звонок на то чтобы переписать его на чем-то другом, например том-же питоне. Потому что начинают вылезать куча проблем по поддержке и расширению кода. Банально, корректно попарсить входные параметры это целая головная боль. Да, стековерфлоу предлагает кучу вариантов с getopt/getopts/while, но после того как код написан, он выглядит действительно страшно. Как-либо проворачивать данные в шелле это целый ад, ибо требуются сотни грабель с экранированием, кучи проверок, и целые гирлянды из awk/sed/tr и прочих вещей. Каких-либо нормальных структур данных типа тех же списокв/мап шелл не поддерживает, как и форматов, то есть пролетающие json/xml/yaml приходится парсить питоном/jq и еще кучей дополнительных тулов или самописными граблями которые тебя рано или поздно подставляют. Приходится уходить на питон, но там начинается свой головняк с виртуаленвами, пипом и прочими прелестями.
Полностью согласен, но стоит добавить, что шелл добавляет боли в части разницы между диалектами sh/bash (sh — он типа везде, а bash — не совсем). Еще есть даже разница между разными версиями bash (о, черт!), хотя во всех современных дистрибутивах Линукс он плюс/минус одинаков.
Что еще выморозило: некоторые команды между Linux/MacOS/Win имеют разное поведение. Например, xargs не имеет прекрасного ключа -r при запуске под Mac. А этот ключ, между прочим, позволяет не фильтровать лишний раз ввод. Я представляю себе сколько еще бойлерплейта придется написать, чтобы проверить наличие необходимых фич и сделать переносимый шелл-скрипт.
Это вы еще под solaris не писали :).
но там начинается свой головняк с виртуаленвами, пипом и прочими прелестями.

Попробуйте pipenv — он облегчает работу, но его правда тоже надо сначала установить
головняк с виртуаленвами, пипом и прочими

Честно говоря я много слышал про какие-то проблемы, но не очень их понимаю, есть pip для тех кто хочет чего-то стандартного и работающего, он умеет и в систему ставить, и в юзера и в виртуальные окружения (что в посте и продемонстрировано), какие проблемы тут у кого возникают?
Ну например тем, что по дефолту этого нет, соответственно надо писать враппер который готовит окружение, обычно на том же shell :). Так же бывают хитрые ограничения например когда к pip нету доступа, или он через прокси завернут.
Не очень понятно когда такое возможно.
Например, в приватном облаке.
вобщем понятнее не стало о какой проблеме речь
Конкретный пример: есть код на питоне который обновляется и его по хорошему надо крутить в виртуаленве чтобы отвязать его от конкретной системы, а чтобы крутить его в виртуаленве надо этот виртуаленв поставить, чтобы не ходить и не делать это руками (потому что много разношерстного кода) появляются всякие обертки.
Так а что/кто мешает поставить venv?

Пожалуй самая главная проблема всех этих супер-пупер удобных, мощных, выразительных, и тэ дэ и тэ пэ в том, что эту безумную дыру ничем не заткнуть, буде понадобится. Нет песочницы, кто угодно может подключить себе что угодно и делать что угодно (это кстати и ко многим встраиваемым языкам относится, единственный, где об этом подумали — Lua). Удобство не должно мешать контролю. А то как-то читал статью, где пытались ограничить встраиваемые возможности питона — сколько там дыр, чтоб вылезти из песочницы и импортнуть то, чего импортировать не положено. Прям напоминает бородатую историю со входом в винду через справку

Ну это касается также и традиционных shell'ов.
Всё так, но это не значит, что нет шансов на изменение, когда-то легаси начинает отмирать, вот когда-то перл был везде и много чего на нём было написано, где он теперь? Во freebsd например давно из базовой поставки выпилили.
busybox — «is a ...»
Неудобство vi убивается его изучением. Милейший редактор.
Неудобство sh убивается его изучением.
Неудобство от милейшей поделки испытаете в режиме восстановления не зная shell и не имея своей поделки под рукой.
Тут разные проблемы, вы потеряли причинно-следственную связь.
Неудобство vi превращается в удобство vi после его изучения. А якобы неудобство sh остаётся якобы неудобством sh в сравнении с якобы удобством Python.
Абсолютно никакая причинно-следственная связь не избавит нас от факта что sh, bash и компания устарели и являются куском теплой массы. Даже, кто бы мог подумать, PowerShell является более удобной и современной заменой. Ну а то что sh не будет заменен в ближайшее будущее, потому что он уже плотно пустил корни везде (до недавнего времени даже init системы были на баше; хотя ярые противники systemd сейчас будут говорить что раньше было лучше) — это уже совсем другая история.
Системди не юниксвейный (хотя у него куча преимуществ, отрицать не буду), инит простой и умещается в кармашек (переносимость ПО даёт возможность более лёгкой миграции сферы деятельности в IoT из SRE или наоборот, в общем универсальный инструмент всегда лучше) а PoSh — это отврат. И вообще… бытует мнение, что лучшим *nix-админом становится BSD-админ. Я не проверял и не разу не трогал фрю, но почему-то верю на слово. А значит… может «трава» действительно «была зеленее»?
Но ведь нужно сначала изучить питон… ))
Считается, что это является более простой задачей относительно изучения баша (если отбрасывать тех ребят, которые с двухтысячного пишут на перле и просто принципиально отметают всё новое — так оно и есть). Хотя для меня питон слишком уж… красивый. Да, наверное он крут тем, что с помощью него можно быстрее всего выразить мысль, но… запрет смешивания табов и пробелов и подобная джавоподобная корпоративщина немного сковывают в рамки.
Питон изучать намного проще и полезнее, он логичный и применяется очень широко.
bash тоже применяется очень широко. Те же пайплайны, инит-скрипты и прочее. Но за пределами этой утилитарщины — нет, bash особо не нужен, в отличие от python. На котором реально можно сложные программные системы создавать.
sh универсален. Python — нет. Тем более третий. Вот когда в каждом чайнике и кофеварке будет python — тогда и поговорим.
Вы не мне это говорите, я на Вашей стороне. :)
Python хорош в нормально функционирующей системе где можно сказать, что каждый из отдельных кусочков этого интерпретатора и его библиотек не нуждается в проверке.
Shell монолитен. Он либо работает, либо не работает. Если не работает шелл, то надо посмотреть в другом режиме или другим экземпляром.
Мне к сожалению часто попадают системы в которых нет необходимых библиотек для функционирования той или иной прикладной программы. К прикладным я отношу и python, как язык программирования с огромным набором модулей.
Поскольку статья ни о чём, могу только заметить, что питон полностью не подходит на роль командной оболочки.

По мне так лучше tcl нету скриптового языка. А если иметь ввиду еще и expect ...

Авторы в первом же абзаце в ридми на гитхабе пишут:

«The idea for xonsh first struck while I was reviewing the Bash chapter (written by my co-author Katy Huff) of Effective Computation in Physics. In the book, we spend a bunch of time describing important, but complex ideas, such as piping. However, we don’t even touch on more ‘basic’ aspects of the Bash language, such as if-statements or loops. Even though I have been using Bash for well over a decade, I am not even sure I know how to add two numbers together in it or consistently create an array. This is normal.»

Кажется, что это классическое «я не осилил, поэтому придумал свое». Сколько уже фреймворков, языков и библиотек было создано по этой причине.
Особенно если мы говорим о пайпинге. Ведь на баше это `ls | grep abc` а вот на питоне будет морока та еще.
вы путаете shell и unix tools, от второго никто не предлагает отказаться.
и зачем они нужны (в python)? subprocess check_call и поехали? А ничего, что там накладные расходы будут даже больше, чем в случае использования шелла напрямую?
не распарсил, поясните мысль
Расшифрую.
Если мы коммитимся на использование python окружения — нам не нужны пайплайнинги, т.к. пайтон на батарейках и умеет почти все из коробки (листинг директорий, поиск текстов и т.п.).
Если же пытаться использовать сторонние утилиты через вызов subprocess.check_call, то можно задействовать пайплайнинг, но накладные расходы все равно выше, чем при попытке утрамбовать такую конструкцию в однострочник bash. Не говоря уже о зависимостях от внешних бинарей. Либо, если руками собирать pipe, то там столько бойлерплейта будет, что проще вздернуться.
Не согласен, все-таки unix tools это специализированный инструмент, который конечно же удобнее в простых случаях и накладные расходы тут настолько мизерные, что нет смысла их обсуждать, я когда ввожу ls в xonsh не вижу никаких накладных расходов которые бы заставили меня писать
import os; os.listdir('.')
даже если import бужет сделан заранее.
Не говоря уже о более продвинутых тулзах типа tree если продолжать пример со списокм файлов.
Но это не означает автоматически, что получилось плохо/хуже.
Автоматически — нет. Но авторы первым аргументом приводят то, что им они не осилили баш, а не то, что у него есть фундаментальные недостатки, которые они нашли, как исправить. Кажется, что решения в духе «чот там слишком сложно, там же должно быть просто, щас все по-быстрому накидаем» чаще оказываются скорее плохими, чем хорошими.
Ну с моей точки зрения про баш это оправдано, вопрос ведь не в том, что его нельзя осилить, вопрос в том нужно ли тратить усилия на такое уродство?
Предложите альтернативы.
Как говорится, «лучше старый проверенный друг, чем два новых».
И «старый конь борозды не испортит» (в плане того, что все эти bash/unix tools отлажены десятилетиями).
Так сей пост и описывает альтернативу.
Вы сейчас шутите? xonsh — альтернатива?
А можно что-то нормальное?
А что в вашем понимании «нормальное»?
Ну, не знаю. Что может стать стандартом де-факто.
Например, zsh/fish — еще куда ни шло.

/молодцы минусовать, если мнение не нравится. Видимо есть только два мнения -мое и неверное? толерантнее надо быть/
Да тут никого ваше мнение не интересует, может интересовать аргументированная позиция, но пока с аргументами у вас никак.
Кому надоело ездить на работу на лошади — вот наша альтернатива — питон верблюд. Какую из доальтернативных задач эта альтернатива решает, никто не может внятно обьяснить.
Ну если кому-то кажется что с шелом всё нормально, то конечно ему ничего менять не нужно, с моей же точки зрения шелл и его синтаксис это лишняя сущность, лишний, причём с очень уродливым ситнтаксисом, язык, при том, что есть, повсеместно применяемый скриптовый язык с очень хорошо выглядящим синтаксисом.
Уродливый синтаксис это дело вкуса. Верблюд ведь красивше лошади? ;)
КМК основная задача шелла типа bash — удобно запускать разные другие программы, с этим у него все нормально. А для программирования есть много других языков.
Я вообще не понимаю почему нужно менять специализированное решение (shell + unix tools + возможности расширениями утилитами, которые работают через консоль и консольные аргументы) ОБЩИМ решением, которым является python.

Возможно, что нужно попытаться поменять мировоззрение и пытаться не засунуть вызовы этих внешних утилит в python (что действительно неудобно), а пользоваться уже существующими примитивами в python. Т.е. примеры:
— хотим получить список файлов и сделать операцию над ними — пользуемся модулем os (listdir и поехало)
— хотим скачать страницу из интернета -пользуем requests или/и urllib
Но фишка в том, что в простых случаях проще дернуть curl, чем писать простыни шаблонного кода на python.

Короче — такое себе.

А вообще, конечно, вспоминаю себя, когда я пытался в консоли DOS на Spectrum'е ввести 2+2 и мне оболочка говорила, что команда не найдена. Расстройство было жуткое — какие же компьютеры глупые )))) а всего лишь нужно было немного изучить командный язык.
Так никто и не предлагает заменять unix tools, речь только об отказе от шелла как языка программирования автоматизации.
worldmind просто нужно разделять котлеты и мух. Серьезную автоматизацию — никто на баше и не предлагает делать. Видимо, критерии серьезности у всех свои. Вот те же ETL (работа с БД, обработка данных и пр.) меня не обламывает писать на python, но я готов брать на себя поддержку среды, в которой они выполняются.

А условный скрипт запуска сервиса, проверки наличии файла, переконвертации из формата в формат, скачивания сайта рекурсивно и пр. — проще наговнякать на баше.

Нужно подбивать подходящий тулинг.

А самое милое дело — хорошо написанные скрипты на python практически ничем не отличаются от консольных утилит и точно так же интегрируются с другими unix tools (pipelining, коды возврата и пр. пр.). Но как бы есть определенная разница с однострочниками на xonsh

Я использую уже около года fish. Правда сам не могу объяснить почему. Вроде и удобная оболочка, но по некоторым вещам из bash/zsh до сих пор скучаю.


По теме: всегда не понимал bash/zsh. Мне кажется, что и язык и реализация этих оболочек какие-то архаичные и эклектичные. Скрипты на bash/zsh кажутся слепленными из палок и изоленты — чуть тронь в любом месте, и все развалится (часто так и происходит). Я знаю, что на shell писались (возможно, пишутся до сих пор) проекты размером в сотни тысяч строк, но это сущий кошмар в поддержке.


Странно, что до сих пор никто не сделал нормальный shell с нормальным читаемым языком внутри… Fish, мне кажется, ближе всех подошел, но и в нем остаются недостатки, кроме того, он не очень популярен.

PowerShell же.

Синтаксис шелла ужасен с точки зрения малознакомого с синтаксисом шелла. Как и любой язык он обладает большими и малыми недостатками.


Аналогично синтаксис Питона ужасен с точки зрения человека, малознакомого с Питоном. Наверняка Питон тоже обладает большими и малыми недостатками. Чего стоит его зависимость алгоритма от количества пробелов.


Более важно, что шелл есть везде, Питон — нет.

Все еще хуже. Шелл есть везде, и как выше заметили — монолитен. Он либо работает, либо нет.
Python — он уже есть как минимум двух несовестимых версий. И требует рабочего окружения. А оно запросто может быть или сломано (например, я сталкивался с таким — stackoverflow.com/questions/47197083/python-pip-error-just-after-fresh-install ), или вам нужны модули какой-то определенной версии, которые или не установлены, или НЕ МОГУТ быть установлены в рамках одного, системного окружения.
Аналогично синтаксис Питона ужасен с точки зрения человека, малознакомого с Питоном.

Как раз на мой взгляд синтаксис питона для незнакомых с ним наиболее понятен
>Аналогично синтаксис Питона ужасен с точки зрения человека, малознакомого с Питоном

Уж лучше питон чем перл
а вообще каждая тулза должна юзатся для определенной нужды, и если есть возможность пользоватся одной тулзой с модулями которые позволят выполнять работу для других сред то зачем заменять эту же тулзу? я вот например в баше могу вызвать и повершел и еще кучку всякого разного и спокойно выполнить нужные мне задачки. тоже самое и в повершелке. как бы можно писать что вот вам тулза которая похоронит остальное и она будет крутая, но зачем такое писать не пойму. Если есть гайка и к ней ключ которым ее закручивать то это не значит что болгарка выполнит эту задачу лучше… исправьте если я не прав
Пользуюсь xonsh в guake (выездной консоли) — очень удобно, и шелл и калькулятор (мой основной use case питона) всегда под рукой по одному и тому же hot key, можно заранее прогрузить все модули которые часто использую, numpy, pandas и пр.

Заметил только что xonsh иногда призадумывается секунд на 2-3 после долгого простоя — никто не сталкивался с таким явлением, как оно лечится?
В смысле задумывается? Не сразу выезжает консоль? Это скорее не в xonsh дело.
Нет тормозит именно xonsh, начинаешь печатать, а эхо от него только через пару секунд появляется, c bash такой проблемы не было
Я с таким не сталкивался, версия самая новая?
Баш прекрасен!)
image
Good new for everyone: в xonsh наконец завезли возможность использовать произвольный питон в виртуальных окружениях, обновил статью, всем радоваться и тестить.
Если в системе есть python 3.7, то можно добавить плагин для автозагрузки переменных окружения для проектов
sudo apt-get install direnv
or
sudo snap install direnv
pip3 install --user xonsh-direnv

# to .xonshrc
xontrib load direnv

# for first load
direnv allow

пока не всё гладко, но в минимальном виде работает.
Уже и пофиксили
А ещё можно сделать свои хуки, например чтобы генерировать TAGS файл для проекта, после xontrib load vox:
@events.vox_on_activate
def post_activate(name, *args, **kwargs):
    print('Generate TAGS file here')
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации