import sh # подготовка команды к запуску cmd = sh.Command(name, search_paths=None)
name
- команда терминала или полный путь самой команды,search_paths=None
- список всех путей для поиска команды с именем name
.Вызов этого класса создает экземпляр Command
, где name
- это имя программы, которая существует в пользовательской переменной $PATH
, или представляет полный путь самой программы.
from sh import Command ifconfig = Command("ifconfig") ifconfig = Command("/sbin/ifconfig")
Если указан search_paths
, это должен быть список всех путей для поиска имени программы.
Объект Command
представляет собой программу, которая существует в системе и может быть запущена в определенный момент времени. Экземпляр Command
никогда не запускается, для этого создается экземпляр RunningCommand
.
import sh # подготовка команды к запуску lscmd = sh.Command("/bin/ls") # запуск команды с параметрами RunningCommand = lscmd("-l")
Экземпляр Command
может принимать форму объекта, созданного вручную, или объекта, созданного с помощью динамического поиска:
import sh ls1 = sh.Command("ls") ls2 = sh.ls assert ls1 == ls2
Command
определяет 1 метод:Command.bake(*args, **kwargs)
:Возвращает новую команду с *args
и **kwargs
, зашитыми в нее позиционными и ключевыми аргументами соответственно. Любые будущие вызовы возвращенной команды будут автоматически включать переданные *args
и **kwargs
:
from sh import ls long_ls = ls.bake("-l") print(ls("/var")) print(ls("/tmp"))
Command
:Аргументы sh.Command()
должны быть разделены, например, следующий код не работает:
lscmd = sh.Command("/bin/ls -l") tarcmd = sh.Command("/bin/tar cvf /tmp/test.tar /my/home/directory/")
Будет поднято исключение CommandNotFound(path)
, даже если указан правильный полный путь.
Правильный способ:
lscmd = sh.Command("/bin/ls") lscmd("-l") tarcmd = sh.Command("/bin/tar") tarcmd("cvf", "/tmp/test.tar", "/my/home/directory/")
Command.bake
.Модуль sh
может "зашивать" аргументы в команды. По сути, это частичное приложение, как в случае с functools.partial()
.
from sh import ls ls = ls.bake("-la") print(ls) # "/usr/bin/ls -la" # resolves to "ls -la /" print(ls("/"))
Идея здесь в том, что теперь каждый вызов команды терминала ls
будет иметь уже указанные аргументы '-la'
. Вшивание параметров команды может стать очень полезной, если комбинировать ее с подкомандами:
from sh import ssh # Каждый раз передавать много параметров # не по питонически, особенно если эта команда # вызывается много раз и на разных серверах iam1 = ssh("myserver.com", "-p 1393", "whoami") # зашиваем параметры в команду ssh myserver = ssh.bake("myserver.com", p=1393) print(myserver) # "/usr/bin/ssh myserver.com -p 1393" # выполнит "/usr/bin/ssh myserver.com -p 1393 whoami" iam2 = myserver.whoami() assert(iam1 == iam2) # True
Теперь, когда вызываемый объект myserver
представляет команду ssh
с параметрами, можно легко вызвать что угодно на сервере:
# "/usr/bin/ssh myserver.com -p 1393 tail /var/log/dumb_daemon.log -n 100" myserver.tail("/var/log/dumb_daemon.log", n=100)