简单的外壳式进程调用

mocksh的Python项目详细描述


mocksh是一个用于在python中编写shell脚本的库。它使外部
命令可用作函数,并提供使用其
结果的可访问方式。它试图复制sh(bourne shell)的语义,当它们在python中有意义时。

运行到完成,并且输出显示为
,而不被捕获:

…代码块::python

>>from mocksh import sh
>>sh.echo("hello,world")
hello,world

代码块::python

>;>;sh.false()
回溯(最近一次调用的最后一次):

mocksh.commanderror[1]:命令"false"失败,状态代码为1

此最基本的形式对于为其副作用运行的命令非常有用。默认情况下,不会捕获命令输出,因为它通常很有用。
如果出现错误,它会提供异常
不知道的额外信息。

——
——
——
————————————————————————————————————————————————————————————————————————笨拙地插入
中间,就在参数前面:

…代码块::python

>;>;str(sh.echo.capture_uu("hello,python"))
"hello,python\n"

进程不会立即返回字符串。你必须告诉它你想如何访问输出:


…代码块::python

>;>;字节(sh.dd.capture(if=/dev/urandom,'count=1,'bs=16'))原始字节
b'w\xc4k\xd9\x04\xa7\x8f\x0el\xe9\xb0\xa1(\x8f\tp'
>;,对于sh.seq.capture中的num(3):逐行
…print(num)
1
2
3
>;>;list(sh.shuf.capture_u('-n',5,'/usr/share/dict/words')
["upgrading","humongous","thesauri","candidly","drools"]

在命令完成之前,以这种方式调用的命令立即返回。
这意味着输出如果输出很大,可以逐行处理,而不会浪费内存


----
piping
----


另一种特殊的方法"pipe"允许您构建管道:

。代码块:python

>;>;sh.fortune.pipe().cowsay();就像"fortune"cowsay一样
/
--------
^ ^
(oo)\\\\\\\\\
(\\\)\/\
--w



就像您对"sh"对象调用命令一样。


代码块::python

>;>str(sh.fortune.pipe\.rot13.capture\')类似于"fortune rot13"
"lbhe cerfrag cynaf jvyy或fhprprfshy。\n'

----
测试默认情况下,命令失败时会引发异常,但这并不总是可取的。有时您只想测试命令是否成功。
`` test`特殊方法可用于:

…代码块::python

>;>;如果sh.ping.test('-c',1,'fake.domain'):
…print("fake.domain已启动")
…其他:
…print("fake.domain is down")
ping:fake.domain:name or service not known
fake.domain is down

==
==
==安装
==



$pip install mocksh

你r scripts文件夹。

==
==
高级用法
==
==

----
其他参数形式
----



某些命令有子命令。例如,``git``具有``git status``和
``git commit``。它们可以用一个点隔开:

…代码块::python
>;>;sh.git.status()
在branch master



命令名中的下划线将转换为破折号,因为许多命令名中都有破折号,但python不允许名称中有破折号。要运行名称中有下划线或任何奇怪字符的命令,可以使用索引语法:

。代码块::python
>;>;sh.units\u cur()不工作,转换为units cur
回溯(最后一次调用):

filenotfounderror:[errno 2]没有这样的文件或目录:"units cur":"units cur"
>;>;sh['units_cur'](works

>;>>sh.sudo['units_cur'](




您还可以使用多个参数索引。这提供了一种定义别名的简单方法:

。代码块::python
>;>;l h=sh.ls['-l','-h']
>;>;lh('/')
总共16k
drwxr-xr-x 1根目录2.4k 7月14日08:26 bin


——
——
——
——命令选项
——
——

选项可以作为常规参数或关键字参数传递:

。代码块::python

>;>;sh.curl('-l','--data','test','httpbin.org/post')\wordy,但是透明的

>;>;sh.curl('httpbin.org/post',l=true,data='test')\fancy,但是不透明的


生成相同的命令。

选项根据一些规则进行处理。

*一个字符长的选项是短选项,其他选项是长选项。这意味着"v"被转换为"v",但"verbose"被
转换为"verbose"。
*下划线(``````````)被转换为破折号(``-```)。这是因为
python不允许在关键字参数中使用破折号。`` cookie-jar``变为
``--cookie-jar`.
*如果参数值为'false`,则将其丢弃。如果值
``true`,则只添加标志。否则,键和值都将被添加。`` l=true``变为`-l``,``data=-test``变为
``--data test``.
*对于长选项,尽管只有一个破折号,但可以用破折号开始
参数。'Java-jar…''可以表示为
`sJava[JavaJava]( *选项被插入在命令名之后和其他参数之前。
BR/>这足以应付大多数程序。但是如果它不按您的要求执行,那么坚持使用简单可靠的表单总是一个不错的选择。

-
-
特殊选项
-


以下划线结尾的关键字参数不会添加到命令中,
而是用于特殊行为。`` mocksh``有几个特殊的关键字
参数,任何其他参数都被转发到``subprocess``(不带
下划线)。

例如,要将命令输出附加到文件:

代码块::python
sh.rsync('-pr'、'somedir'、'somehost:',stdout_stdout_,而不是stdout

,这大致相当于使用了"subprocess"`:

。代码块::python
>;>import subprocess
>;>open('log.txt','a')为f:
…subprocess.run(['rsync','-pr','somedir','somehost:'],stdout=f)

如果命令
失败,则自动引发异常。`` true``默认情况下。
*`` input``:发送到命令的标准输入的字符串或字节。
*`` wait``:是否等到命令完成后再返回。
若要在后台运行命令,请添加`` wait`` false`。
*`` timeout`:可选,在引发"subprocess.timeoutexpred"异常之前要等待多少秒。
*"capture-stdout":如果"true",则捕获命令的标准输出。
"capture-stdout=true"等同于"stdout=sh.pipe"。如果只捕获stderr,
将命令转换为字符串将给出stderr输出。

----
process objects
----


commands返回``mocksh.process``对象,这是
``subprocess.popen``的子类。它可以像"popen"的常规实例一样使用,
,但有其他特性,其中大多数特性都包含在其他部分中。

管道中的进程将具有"tail"属性,设置为管道中以前的
命令。如果管道开始处的进程有一个
open``stdin``属性,则其'`stdin``属性设置为该属性。

``process.wait``是管道感知的,将等待整个管道
完成,通过适当的超时处理。

"process.check-returncode"方法会引发"commanderror",即使手动检查时
"check=false"。

"captured"属性如果被捕获,则指向"stdout";如果被捕获,则指向"stderr"。如果两者都被捕获,``stdout``和
``stderr``必须直接寻址。

-
-
-
异步命令
-
-


它们可以用作上下文管理器:

…代码块::使用sh.wget('some.large/file.ext'):
一些别的东西……
…#wget现在保证已经完成,并且会抛出一个
…#如果失败则出现异常
…使用('file.ext')

,因为``capture`也在后台运行进程,所以您可以等到稍后再收集输出。你可以循环它的行:

…代码块::python
>;>;用于sh.long_process()中的行:
…处理(行)

或者您可以一次性收集它:

…代码块::python
>;>proc=sh.昂贵的计算(
>;>output=str(proc)

----
异常处理
----


异常类型是
可作为``sh.commanderror```(注意下划线)访问的。


异常是针对不同的返回代码和信号的子类。
可以使用``code``类方法访问子类。例如:

…代码块::python
>;>;尝试:
…sh.false()
…除了sh.commanderror代码(10):
…打印("以10退出")
…除了sh.commanderror代码(1):
…print("exited with 1")
exited with 1

可按名称引用信号:

。代码块::python
>;>;尝试:
…sh.tcc('-run','-',input_='include<;stdio.h>;int main(){puts(0);}')
…除了sh.commanderror\u.code('sigsegv'):
……

----
命令对象
----

``sh``是一个``mocksh.command``对象。像"sh.echo"和"sh.ls['-l','-h]``这样的命令也是"command"对象。

`command``对象可以包含一组为"process"准备好的参数。
这就是管道的实现方式:``_pipe``返回一个新的``command``
对象,将``tail``设置为最后一个``process``。

如果您厌倦了一直键入``.capture``的操作,您可以
创建自己的启动程序,如下所示:

代码块::python
>;>;import mocksh
>;>;mysh=mocksh.command(capture\u stdout=true,wait=false)
>;>;str(mysh.echo('test'))
"test\n"

>>---------------------------
为什么应该使用子流程而不是
--------

它试图复制sh的语义,但是sh的语义与python的语法不兼容。

通过像"subprocess.run<;https://docs.python.org/3/library/subprocess.html"subprocess.run>;` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `<;http://amoffat.github.io/sh/>;``(与本文档中
``sh``一词的其他用法无关)
*`plumbum<;https://plumbum.readthedocs.io/>;``u




欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java无法更新Maven配置   Java中错误和异常的区别?   java从日期开始获得小时、分钟和秒?   使用jsonpath使用数组索引进行java解析   java如何从改造中读取json响应   Java:封装概念   Scala的java Play Framework:[类型控制器不是包控制器的成员]   java JPA Hibernate使用criteria builder生成的左连接被忽略   使用mvn测试版本号时,java Maven无法解析依赖项   java安卓的vitals和异常处理   java组织。springframework。网状物绑定参数的MissingServletRequestParameterException   java JSON解析在Android应用程序脱机时崩溃   java如何降低SmartMaterialSpinner的高度?   java有一种在使用矩阵时不拉伸位图的方法。位图上的polytoply()?   java arraylist有问题吗   java调用dispose()不会关闭JFrame   java主机环境安全   java是否产生/加入释放监视器锁?   java包含json文件并将其读入生成的maven中。jar文件