В моем предыдущем посте у меня было немного разглагольство о людях, не изучающих характерных людей языка, который является Bash, и, в целом, в том, что языки оболочки в целом, приводящие к сильному откровенно ужасному сценарию в дикой природе.
Я написал так много сценариев Shell – и поставил столько акцент на чистый, многоразовый код в Shell – ради горстки ключевых операций, которые просто должны быть командами, где я бы предпочел, чтобы управлять гораздо более приятным кодом.
Итак, сегодня я поворачиваю это прямо вокруг: вместо того, чтобы пытаться применить чистый код в сценарии оболочки (и сбой на скалистых берегах других Devs ‘» Но это просто скрипт оболочки »), я собираюсь принести лучшую часть снарядов в Python: ShellPipe.py
Факт вопроса в том, что многие сценарии оболочки используется для склеивания других инструментов вместе, и это, безусловно, где он превосходит. Python Напротив, как и большинству других языков, требует небольшого прохождения и отслеживания выходов и входов для достижения того же эффекта, и, вообще более комфортные языки, не так красноречивые для задачи унификации разрозненных, неинтерфазных инструментов.
По этой причине я продолжал писать сценарии Bash в качестве клея, а не пытаться сделать это, проходящее вокруг. По этой причине, в свою очередь, я написал обширные суммы поддержки Bash, который действительно должен был быть либо написан на другом языке, либо дозадался полностью, были ли это не для их характерных ситуаций.
На последнем посте у меня есть комментарий от @XTOFL, указывающего на то, что у них было быстрые поехать в повторное целенаправленное побитовое или оператор в Python в трубном операторе. Они расширились на эту технику в более позднем посте с их предложением для функций цепочки, стиль труб, которые в то время как в целом, не соответствует моим более основным потребностям Sysadminy.
Вчера я вспомнил свой маленький комментарий и решил пойти на него сам.
Я очень горжусь собой. Хотя, возможно, я должен чувствовать тяжело стыдно Отказ Теперь я могу сделать это в сценарии Python:
from shellpipe import sh # Run a command sh() | 'git clone https://github.com/taikedz/shellpipe' # Chain commands, use strings or lists, embed quoted strings, print to console: sh() | "find shellpipe/shellpipe" | 'grep -vE ".*\\.pyc"' | ['du', '-sh'] > 1
Предопределенные команды, используйте их в цепях
DOCKER_PSA = "docker ps -a" GREP = "grep {}" def look_for(subname): found = sh() | DOCKER_PSA | GREP.format(subname) return str(found).split("\n")
Я бы в идеале хотел сделать что-то вроде этого:
mysql_result = sh(f'mysql {user} -p{pass} db') < """ CREATE TABLE ... """
Что, к сожалению, невозможно, в то время как также обеспечивает немедленное выполнение каждого шага – в первую очередь будет проверять компаратор (LHS), прежде чем правая рука (RHS) проверяется. Моя текущая реализация запускает шаг трубы по созданию, что означает, что сама команда выполняется до обработки «перенаправления».
Если я отложу выполнение до тех пор, пока после этого перенаправления (это было на самом деле, как работала первая реализация), мне пришлось бы сделать что-то подобное:
mysql_result = (sh(f'mysql {user} -p{pass} db') < """ CREATE TABLE ... """).run()
Что намного менее элегантно. Кроме того, наличие внешнего скрипта в фактическом файле лучше практиковаться в большинстве установок, поэтому то, что мне действительно нужно сделать с текущей необходимостью
with open("script.mysql", "r") as fh: mysql_result = sh(f'mysql {user} -p{pass} db', stdin=fh)
в любом случае, в любом случае, более разумно. Не сложившиеся другие сценарии в вашей программе, храните их аккуратно (он сказал, что заполняют команды оболочки в программу Python).
Что это за колдовство ??
Я угнал побитовой или инн. Или, по крайней мере, у меня есть с целью моего пользовательского класса, Shellpipe
(который просто предоставляется благодаря ферме присваивания как Sh
).
Какой шеллапс определяет свою __or __ ()
Функция, которая называется в любое время, это помещено в х |. y
Операция в Python. Подобные вещи существуют для __ И__
( &
Bittive и операторский ремин) и __lt__
(Менее, чем операторский ремин), чтобы иметь возможность использовать пользовательские, сложные классы как сортируемые элементы.
Это .__ или __ (что)
Обычно должен просто вернуть объект того же типа, что и Это
и что
, но мы можем немного оскорбиться, не требуя одной стороны, чтобы быть того же типа, что и другая. Возможно, мы могли бы вернуть все, что мы хотим.
При вызове х |. y
, только __or __ ()
Объекта на левой стороне оператора выполняется, и эта пара, а затем обычно возвращается новый объект, который является объединением двух.
Призывая Shellpipe () | «Строка»
Я получаю выгоду из этого, позволяя Shellpipe
Функция, чтобы увидеть, что на другой стороне операции есть строка, и поэтому она включает, что в Shellpipe (...)
Его собственным – и результатом заключается в том, что строка стала прогонфекционным куском кода, таким образом.
Похоже, это (скорее, именно это именно):
def __or__(self, other): our_out = None if self.process: our_out = self.process.stdout if type(other) in (str,list,tuple): other = ShellPipe(command_list=other, stdin=our_out) return other
Так что происходит, когда я вызываю Shellpipe () | "cmd1" | "cmd2"
?
- В этом случае первые LHS (пустой экземпляр) ничего не делают, так как он не был построен с командой (Это могло быть, двенадцать и два шестерки, как мы говорим здесь)
- И это превращает RHS в
Shellpipe («CMD1»)
и возвращает это –CMD1
немедленно выполняется в результате определения CMD1
Теперь новый LHS, и он держит удержание своего производственного потока, передавая его в строительство нового RHS,Shellpipe («CMD2»,)
И так далее. Довольно просто, правда. После достижения конца цепи, последний элемент, который был выполнен, также возвращен и так в
mypipe = sh() | "cmd1" | "cmd2" | "cmd3"
MyPipe
на самом деле Shellpipe («CMD3»)
Объект, созданный CMD2.
Это выходная часть этой последней команды, которую мы можем проверить с mypipe.get_stdout ()
Но почему??
Это полезно и лучше, чем использование подпрокат. Popen ()
напрямую? Это, безусловно, в основном синтаксический сахар, и импортирующие особенности из одного языка в другое не всегда лучший ответ, но мои случаи использования повернули больше к «Я хочу использовать Python для большинства вещей, но есть один инструмент, который можно использовать только в качестве команды». Струнные и ручье манипулирование легче в Python (после того, как вам нужно управлять контекстом за одну строку), и богатый опыт печатания – который позволил __or __ ()
Перегрузка в первую очередь – лучше, чем в скриптах оболочки.
Недостатком моей реализации является то, что она запускает каждую команду полностью, прежде чем передаваться на следующую – если команда должна создавать большое количество выходов, которое будет храниться в файловом дескрипторе (и, вероятно, при этом в памяти), прежде чем их передавать Следующая команда. Кроме того, если несколько команд занимают значительное количество времени для запуска, это тоже плохо работает.
Но есть только те раз, где что один инструмент Это доступно только в качестве команды, и никто не имеет Python-Package для, легче просто … использовать в качестве команды.
Мой следующий сеанс программирования, скорее всего, будет преобразовывать все сценарии, которые я когда-то писал кучу Bash и поддерживая Bash для сценариев Python, используя ShellPipe, чтобы покрыть угловые чехлы. Я, вероятно, опубликую отчет здесь после того, как я сделал пару, чтобы заметить разницу, которую она сделала – если таковая имеется.
Но Если я рассмотрю Отказ все Отказ код Bash . Я написал Отказ где большая часть этого Отказ Было ли только управление переменными Отказ Ради Отказ Горсть Отказ Команды оболочки трубопроводов и чистый код …
… я чувствую себя оправданным. Это Хорошо мерзость 😌.
Оригинал: “https://dev.to/taikedz/shellpipe-shellpipe-py-is-exactly-what-you-think-12bi”