execution of Linux commands in Python.

2人阅读 评论(0) 收藏 举报
分类:

1. os.system

out = os.system(command_to_use)

This is implemented by calling the Standard C function system(), and has the same limitations.
the return value is the exit status of the process encoded in the format specified for wait(). Note that POSIX does not specify the meaning of the return value of the C system() function, so the return value of the Python function is system-dependent.

2.os.popen(command, mode, bufsize)
return value is a file object, which can be read or written depending on whether mode is ‘r’ (default) or ‘w’.

>>> fd = os.popen('ls', 'r')
>>> for line in fd.read().split():
...     print(line)
... 
a9fdd8b1224a2aa7ff63fd3a4fb20a035f8dcb2b.patch
autotest
Backups
Cache
CachedData
CachedExtensions

3.os.popen(command[, mode[, bufsize]])
Open a pipe to or from command. The return value is an open file object connected to the pipe, which can be read or written depending on whether mode is ‘r’ (default) or ‘w’. The bufsize argument has the same meaning as the corresponding argument to the built-in open() function. The exit status of the command (encoded in the format specified for wait()) is available as the return value of the close() method of the file object, except that when the exit status is zero (termination without errors), None is returned.
the communication could not be bi-directional.

>>> import os
>>> fd = os.popen('ls -la')
>>> for line in fd.read().split('\n'):
...     print(line)
... 
total 704
drwxr-xr-x. 25 root        root          4096 Apr 16 14:36 .
dr-xr-xr-x. 32 root        root          4096 Apr 16 13:59 ..
-rw-r--r--   1 root        root          6062 Mar 19 10:16 a9fdd8b1224a2aa7ff63fd3a4fb20a035f8dcb2b.patch
drwx------   7 autotest    autotest       175 Feb 10 13:05 autotest
drwxr-xr-x   2 root        root            29 Mar  9 09:00 Backups
drwx------   2 root        root           267 Mar  9 09:04 Cache
drwxr-xr-x   3 root        root            54 Mar  9 09:00 CachedData
drwxr-xr-x   2 root        root            21 Mar  9 09:01 CachedExtensions

there are os.popen2, os.popen3, os.popen4, which are obsolete - use subprocess instead.

4.subprocess module
aims to replace functions like os.system, os.popen.

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None)

This does not capture stdout or stderr by default. To do so, pass PIPE for the stdout and/or stderr arguments.

this is equivalent to subprocess.call

>>> subprocess.call(['ls', '-la'])
ls: cannot access mnt: Transport endpoint is not connected
total 704
drwxr-xr-x. 25 root        root          4096 Apr 16 14:36 .
dr-xr-xr-x. 32 root        root          4096 Apr 16 13:59 ..
-rw-r--r--   1 root        root          6062 Mar 19 10:16 a9fdd8b1224a2aa7ff63fd3a4fb20a035f8dcb2b.patch
drwx------   7 autotest    autotest       175 Feb 10 13:05 autotest
drwxr-xr-x   2 root        root            29 Mar  9 09:00 Backups

it seems the output is directly redirect to stdout

import subprocess

cmd = ['ls', '-la']
f = subprocess.run(cmd)
print('-'* 20)
print(f.stdout)

output:

total 3680
drwxr-xr-x 2 root root    4096 Apr 16 17:02 .
drwxr-xr-x 4 root root      33 Apr 16 15:04 ..
-rw-r--r-- 1 root root  508452 Jul 19  2017 glusterfs-3.8.4-18.6.el7rhgs.x86_64.rpm
-rw-r--r-- 1 root root   71404 Jul 19  2017 glusterfs-api-3.8.4-18.6.el7rhgs.x86_64.rpm
-rw-r--r-- 1 root root  174460 Jul 19  2017 glusterfs-cli-3.8.4-18.6.el7rhgs.x86_64.rpm
-rw-r--r-- 1 root root  793156 Jul 19  2017 glusterfs-client-xlators-3.8.4-18.6.el7rhgs.x86_64.rpm
-rw-r--r-- 1 root root  116744 Jul 19  2017 glusterfs-fuse-3.8.4-18.6.el7rhgs.x86_64.rpm
-rw-r--r-- 1 root root  199768 Jul 19  2017 glusterfs-geo-replication-3.8.4-18.6.el7rhgs.x86_64.rpm
-rw-r--r-- 1 root root  369960 Jul 19  2017 glusterfs-libs-3.8.4-18.6.el7rhgs.x86_64.rpm
-rw-r--r-- 1 root root 1497232 Jul 19  2017 glusterfs-server-3.8.4-18.6.el7rhgs.x86_64.rpm
-rw-r--r-- 1 root root      94 Apr 16 17:02 sample.py
-rw------- 1 root root   12288 Apr 16 17:02 .sample.py.swp
--------------------
None
>>> import shlex
>>> command = input()
docker run --privileged=true -it --name gluster registry.access.redhat.com/rhgs3/rhgs-server-rhel7 /bin/bash
>>> cmd = shlex.split(command)
>>> cmd
['docker', 'run', '--privileged=true', '-it', '--name', 'gluster', 'registry.access.redhat.com/rhgs3/rhgs-server-rhel7', '/bin/bash']
>>> obj = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> obj.communicate("uname -r".encode())
(b'', b'the input device is not a TTY\n')
>>> obj = subprocess.Popen(['ssh', 'server2'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> obj.communicate("uname -r".encode())(b'3.10.0-693.2.1.el7.x86_64\n', b"Pseudo-terminal will not be allocated because stdin is not a terminal.\r\nWarning: Permanently added '10.66.8.206' (ECDSA) to the list of known hosts.\r\n")
>>> obj.poll()
0

the child process is dead after communicate

>>> out = subprocess.check_output(['ssh', 'server2', 'uname', '-r'])
Warning: Permanently added '10.66.8.206' (ECDSA) to the list of known hosts.
>>> out
b'3.10.0-693.2.1.el7.x86_64\n'

how to open a shell and communicate?

>>> from subprocess import Popen, PIPE
>>> child = Popen(['ssh', '-T', 'server2'], stdin=PIPE, stdout=PIPE, bufsize=0, universal_newlines=True)
>>> Warning: Permanently added '10.66.8.206' (ECDSA) to the list of known hosts.

>>> child.stdin.write(b'uname -r')
>>> child.stdin.flush()
>>> child.stdout.readline()

the child.stdout.readline() will hang.
the reason from the doc:
Warning Use communicate() rather than .stdin.write, .stdout.read or .stderr.read to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process.

>>> child = Popen(['ssh', '-T', 'server2'], stdin=PIPE, stdout=PIPE, bufsize=-1, universal_newlines=True)
>>> Warning: Permanently added '10.66.8.206' (ECDSA) to the list of known hosts.

>>> child.stdin.write(b'uname -r')
>>> child.stdin.flush()
>>> child.communicate()
('3.10.0-693.2.1.el7.x86_64\n', None)

after communicate, the child process exits. So what if I want to run multiple commands in that ssh session?

my goal here is to run a container and start GlusterFS service on it. So the subprocess must be alive after giving it commands.

# docker run --privileged=true -it --name gluster registry.access.redhat.com/rhgs3/rhgs-server-rhel7 /bin/bash

reference:
https://docs.python.org/3.6/library/subprocess.html#module-subprocess

查看评论

linux ip related commands

  • 2018年01月25日 00:00
  • 1.51MB
  • 下载

Isight unable to evaluate matlab commands的解决办法

这两天在利用Isight进行优化时遇到一个问题,困扰了我很久。用到了matlab模块,优化简单的matlab程序时可以直接运行,复杂的matlab程序就出现“Isight unable to eval...
  • appe1943
  • appe1943
  • 2017-03-24 20:22:31
  • 570

A Practical Guide to Linux Commands, Editors, and Shell Programming(4th) 无水印pdf

  • 2017年10月16日 21:49
  • 28.72MB
  • 下载

A Practical Guide to Linux Commands, Editors and Shell Programming 3rd pdf 0分

  • 2016年09月05日 11:44
  • 62.17MB
  • 下载

利用commands模块执行Linux shell命令

利用commands模块执行Linux shell命令 用Python写运维脚本时,经常需要执行linux shell的命令,Python中的commands模块专门用于调用Linu...
  • chenglinhust
  • chenglinhust
  • 2016-01-09 16:32:35
  • 731

Linux Commands, Editors and Shell Programming

  • 2015年04月01日 18:04
  • 5.11MB
  • 下载

Execution Control Commands

5.9.4.1. source - run script from memory => help source source - run script from memory Usage:...
  • yuyin86
  • yuyin86
  • 2013-02-20 08:59:51
  • 381

A Practical Guide to Linux Commands, Editors and Shell Programming 英文 pdf

  • 2010年09月24日 18:22
  • 22.06MB
  • 下载

5.9.4. Execution Control Commands

5.9.4.1. source - run script from memory => help source source - run script from memory Usage:...
  • story1987
  • story1987
  • 2014-06-04 10:18:38
  • 1295

Linux Commands

  • 2008年05月09日 16:34
  • 178KB
  • 下载
    个人资料
    持之以恒
    等级:
    访问量: 1万+
    积分: 819
    排名: 6万+