大家好,今天小编来为大家解答以下的问题,关于linuxpipe,centos pip这个很多人还不知道,现在让我们一起来看看吧!

一、linux Write failed: Broken pipe一般都是什么原因导致的错误
1、网络通讯中,连接意外中断,比如被人拔了网线;
2、进程间通讯中管道断裂,譬如管道某一端进程僵死;
3、文件描述符终端,多见于*Nix,当退出登录时,虚拟终端断开,导致文件描述符1和2消失;
二、subprocess模块怎么使用
subprocess模块主要用于创建子进程,并连接它们的输入、输出和错误管道,获取它们的返回状态。通俗地说就是通过这个模块,你可以在Python的代码里执行操作系统级别的命令,比如ipconfig、du-sh等。
subprocess模块替代了一些老的模块和函数,比如:os.system、os.spawn*等。
subprocess过去版本中的call(),check_call()和check_output()已经被run()方法取代了。run()方法为3.5版本新增。
大多数情况下,推荐使用run()方法调用子进程,执行操作系统命令。在更高级的使用场景,你还可以使用Popen接口。其实run()方法在底层调用的就是Popen接口。
subprocess.run(args,*,stdin=None,input=None,stdout=None,stderr=None,shell=False,timeout=None,check=False,encoding=None,errors=None)
功能:执行args参数所表示的命令,等待命令结束,并返回一个CompletedProcess类型对象。
注意,run()方法返回的不是我们想要的执行结果或相关信息,而是一个CompletedProcess类型对象。
上面参数表里展示的只是一些常用的,真实情况还有很多。
args:表示要执行的命令,必须是一个字符串,字符串参数列表。
stdin、stdout和stderr:子进程的标准输入、输出和错误。其值可以是subprocess.PIPE、subprocess.DEVNULL、一个已经存在的文件描述符、已经打开的文件对象或者None。
subprocess.PIPE表示为子进程创建新的管道,subprocess.DEVNULL表示使用os.devnull。默认使用的是None,表示什么都不做。另外,stderr可以合并到stdout里一起输出。
timeout:设置命令超时时间。如果命令执行时间超时,子进程将被杀死,并弹出TimeoutExpired异常。
check:如果该参数设置为True,并且进程退出状态码不是0,则弹出CalledProcessError异常。
encoding:如果指定了该参数,则stdin、stdout和stderr可以接收字符串数据,并以该编码方式编码。否则只接收bytes类型的数据。
shell:如果该参数为True,将通过操作系统的shell执行指定的命令。
>>>subprocess.run(["ls","-l"])#没有对输出进行捕获CompletedProcess(args=['ls','-l'],returncode=0)>>>subprocess.run("exit1",shell=True,check=True)Traceback(mostrecentcalllast):...subprocess.CalledProcessError:Command'exit1'returnednon-zeroexitstatus1>>>subprocess.run(["ls","-l","/dev/null"],stdout=subprocess.PIPE)CompletedProcess(args=['ls','-l','/dev/null'],returncode=0,stdout=b'crw-rw-rw-1rootroot1,3Jan2316:23/dev/null\n')>>>subprocess.run("python--version",stdout=subprocess.PIPE)CompletedProcess(args='python--version',returncode=0,stdout=b'Python3.6.1\r\n')>>>s=subprocess.run("ipconfig",stdout=subprocess.PIPE)#捕获输出>>>print(s.stdout.decode("GBK"))
run()方法的返回值,表示一个进程结束了。CompletedProcess类有下面这些属性:
args启动进程的参数,通常是个列表或字符串。
returncode进程结束状态返回码。0表示成功状态。
stdout获取子进程的stdout。通常为bytes类型序列,None表示没有捕获值。如果你在调用run()方法时,设置了参数stderr=subprocess.STDOUT,则错误信息会和stdout一起输出,此时stderr的值是None。
stderr获取子进程的错误信息。通常为bytes类型序列,None表示没有捕获值。
check_returncode()用于检查返回码。如果返回状态码不为零,弹出CalledProcessError异常。
一个特殊值,用于传递给stdout、stdin和stderr参数。表示使用os.devnull作为参数值。
管道,可传递给stdout、stdin和stderr参数。
特殊值,可传递给stderr参数,表示stdout和stderr合并输出。
args参数可以接收一个类似'du-sh'的字符串,也可以传递一个类似['du','-sh']的字符串分割列表。shell参数默认为False,设置为True的时候表示使用操作系统的shell执行命令。
下面我们来看一下两者的组合结果。
In[14]:subprocess.run('du-sh')---------------------------------------------------------------------------FileNotFoundErrorTraceback(mostrecentcalllast)......FileNotFoundError:[Errno2]Nosuchfileordirectory:'du-sh'In[15]:subprocess.run('du-sh',shell=True)175M.Out[15]:CompletedProcess(args='du-sh',returncode=0)
可见,在Linux环境下,当args是个字符串时,必须指定shell=True。成功执行后,返回一个CompletedProcess对象。
In[16]:subprocess.run(['du','-sh'],shell=True).....大量的数据4./文档179100.Out[16]:CompletedProcess(args=['du','-sh'],returncode=0)In[17]:subprocess.run(['du','-sh'])175M.Out[17]:CompletedProcess(args=['du','-sh'],returncode=0)
可见,当args是一个['du','-sh']列表,并且shell=True的时候,参数被忽略了,只执行不带参数的du命令。
总结:Linux中,当args是个字符串是,请设置shell=True,当args是个列表的时候,shell保持默认的False。
run()方法返回的是一个CompletedProcess类型对象,不能直接获取我们通常想要的结果。要获取命令执行的结果或者信息,在调用run()方法的时候,请指定stdout=subprocess.PIPE。
>>>ret=subprocess.run('dir',shell=True)>>>retCompletedProcess(args='dir',returncode=0)>>>ret=subprocess.run('dir',shell=True,stdout=subprocess.PIPE)>>>retCompletedProcess(args='dir',returncode=0,stdout=b'\xc7\xfd\xb6\xaf\xc6\xf7......')>>>ret.stdoutb'\xc7\xfd\xb6\xaf\xc6\xf7C\xd6\xd0\xb5\xc4\xbe\xed\xca\xc7......'
从例子中我们可以看到,如果不设置stdout=subprocess.PIPE,那么在返回值CompletedProcess(args='dir',returncode=0)中不会包含stdout属性。反之,则会将结果以bytes类型保存在ret.stdout属性中。
并不是所有的操作系统命令都像‘dir’或者‘ipconfig’那样单纯地返回执行结果,还有很多像‘python’这种交互式的命令,你要输入点什么,然后它返回执行的结果。使用run()方法怎么向stdin里输入?
importsubprocessret=subprocess.run("python",stdin=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)ret.stdin="print('haha')"#错误的用法print(ret)
这样是不行的,ret作为一个CompletedProcess对象,根本没有stdin属性。那怎么办呢?前面说了,run()方法的stdin参数可以接收一个文件句柄。比如在一个1.txt文件中写入print('ilikePython')。然后参考下面的使用方法:
importsubprocessfd=open("d:\\1.txt")ret=subprocess.run("python",stdin=fd,stdout=subprocess.PIPE,shell=True)print(ret.stdout)fd.close()
这样做,虽然可以达到目的,但是很不方便,也不是以代码驱动的方式。这个时候,我们可以使用Popen类。
用法和参数与run()方法基本类同,但是它的返回值是一个Popen对象,而不是CompletedProcess对象。
>>>ret=subprocess.Popen("dir",shell=True)>>>type(ret)
Popen对象的stdin、stdout和stderr是三个文件句柄,可以像文件那样进行读写操作。
>>>s=subprocess.Popen("ipconfig",stdout=subprocess.PIPE,shell=True)>>>print(s.stdout.read().decode("GBK"))
要实现前面的‘python’命令功能,可以按下面的例子操作:
importsubprocesss=subprocess.Popen("python",stdout=subprocess.PIPE,stdin=subprocess.PIPE,shell=True)s.stdin.write(b"importos\n")s.stdin.write(b"print(os.environ)")s.stdin.close()out=s.stdout.read().decode("GBK")s.stdout.close()print(out)
通过s.stdin.write()可以输入数据,而s.stdout.read()则能输出数据。
三、简述Linux进程间通信的几种方式
一、方式1、管道(Pipe)及有名管道(mkpipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;
2、信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身。
linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction。
实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数。
3、消息队列(Message):消息队列是消息的链接表,包括Posix消息队列systemV消息队列。
有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。
消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
4、共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。
是针对其他通信机制运行效率较低而设计的。
往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
5、信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
6、套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。
起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和SystemV的变种都支持套接字。二、概念进程间通信概念:IPC—-InterProcessCommunication每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到所以进程之间要交换数据必须通过内核。
在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。扩展资料1)无名管道:管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程)。
管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,构成两进程间通信的一个媒介。
数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。
写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。
2)有名管道:不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。
这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间)。
因此,通过FIFO不相关的进程也能交换数据。值得注意的是,FIFO严格遵循先进先出(firstinfirstout),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。
它们不支持诸如lseek()等文件定位操作。
END,本文到此结束,如果可以帮助到大家,还望关注本站哦!