设为首页 收藏本站
查看: 594|回复: 0

python 学习笔记 8 -- Python下调用Linux的Shell命令

[复制链接]

尚未签到

发表于 2018-8-30 07:18:54 | 显示全部楼层 |阅读模式
  有时候难免需要直接调用Shell命令来完成一些比较简单的操作,比如mount一个文件系统之类的。那么我们使用Python如何调用Linux的Shell命令?下面来介绍几种常用的方法:
1. os 模块
1.1. os模块的exec方法族
  Python的exec系统方法同Unix的exec系统调用是一致的。这些方法适用于在子进程中调用外部程序的情况,因为外部程序会替换当前进程的代码,不会返回。( 这个看了点 help(os)  --> search "exec" 的相关介绍,但是没太搞明白咋使用)
1.2. os模块的system方法
  system方法会创建子进程运行外部程序,方法只返回外部程序的运行结果。这个方法比较适用于外部程序没有输出结果的情况。
  [python] view plaincopy
  

  •   >>> import os
  •   >>> os.system("echo \"Hello World\"")   # 直接使用os.system调用一个echo命令
  •   Hello World         ——————> 打印命令结果
  •   0                   ——————> What's this ? 返回值?
  •   >>> val = os.system("ls -al | grep \"log\" ")   # 使用val接收返回值
  •   -rw-r--r--  1 root       root       6030829 Dec 31 15:14 log    ——————> 此时只打印了命令结果
  •   >>> print val
  •   0                   ——————> 注意,此时命令正常运行时,返回值是0
  •   >>> val = os.system("ls -al | grep \"log1\" ")
  •   >>> print val
  •   256                 ——————> 使用os.system调用一个没有返回结果的命令,返回值为256~
  •   >>>
  注意:上面说了,此方法脂肪会外部程序的结果,也就是os.system的结果,所以如果你想接收命令的返回值,接着向下看~
1.3. os模块的popen方法
  当需要得到外部程序的输出结果时,本方法非常有用。比如使用urllib调用Web API时,需要对得到的数据进行处理。os.popen(cmd) 要得到命令的输出内容,只需再调用下read()或readlines()等 如a=os.popen(cmd).read()
  [python] view plaincopy
  

  •   >>> os.popen('ls -lt')                  # 调用os.popen(cmd)并不能得到我们想要的结果
  •   
  •   >>> print os.popen('ls -lt').read()     # 调用read()方法可以得到命令的结果
  •   total 6064
  •   -rwxr-xr-x 1 long       long            23 Jan  5 21:00 hello.sh
  •   -rw-r--r-- 1 long       long           147 Jan  5 20:26 Makefile
  •   drwxr-xr-x 3 long       long          4096 Jan  2 19:37 test
  •   -rw-r--r-- 1 root       root       6030829 Dec 31 15:14 log
  •   drwxr-xr-x 2 long       long          4096 Dec 28 09:36 pip_build_long
  •   drwx------ 2 Debian-gdm Debian-gdm    4096 Dec 23 19:08 pulse-gylJ5EL24GU9
  •   drwx------ 2 long       long          4096 Jan  1  1970 orbit-long
  •   >>> val = os.popen('ls -lt').read()     # 使用变量可以接收命令返回值
  •   >>> if "log" in val:                    # 我们可以使用in来判断返回值中有木有一个字符串
  •   ...     print "Haha,there is the log"
  •   ... else:
  •   ...     print "No,not happy"
  •   ...
  •   Haha,there is the log
2. commands 模块
  使用commands模块的getoutput方法,这种方法同popend的区别在于popen返回的是一个文件句柄,而本方法将外部程序的输出结果当作字符串返回,很多情况下用起来要更方便些。
  主要方法:
  *   commands.getstatusoutput(cmd)         返回(status, output)
  *   commands.getoutput(cmd)                   只返回输出结果
  *   commands.getstatus(file)                     返回ls -ld file的执行结果字符串,调用了getoutput,不建议使用此方法
  [python] view plaincopy
  

  •   long@zhouyl:/tmp/tests$ python
  •   Python 2.7.3 (default, Jan  2 2013, 16:53:07)
  •   [GCC 4.7.2] on linux2
  •   Type "help", "copyright", "credits" or "license" for more information.
  •   >>> import commands
  •   >>> commands.getstatusoutput('ls -lt')      # 返回(status, output)
  •   (0, 'total 5900\n-rwxr-xr-x 1 long long      23 Jan  5 21:34 hello.sh\n-rw-r--r-- 1 long long     147 Jan  5 21:34 Makefile\n-rw-r--r-- 1 long long 6030829 Jan  5 21:34 log')
  •   >>> commands.getoutput('ls -lt')            # 返回命令的输出结果(貌似和Shell命令的输出格式不同哈~)
  •   'total 5900\n-rwxr-xr-x 1 long long      23 Jan  5 21:34 hello.sh\n-rw-r--r-- 1 long long     147 Jan  5 21:34 Makefile\n-rw-r--r-- 1 long long 6030829 Jan  5 21:34 log'
  •   >>> commands.getstatus('log')               # 调用commands.getoutput中的命令对'log'文件进行相同的操作
  •   '-rw-r--r-- 1 long long 6030829 Jan  5 21:34 log'
  •   >>>
3. subprocess模块
  根据Python官方文档说明,subprocess模块用于取代上面这些模块。有一个用Python实现的并行ssh工具—mssh,代码很简短,不过很有意思,它在线程中调用subprocess启动子进程来干活。
  [python] view plaincopy
  

  •   >>> from subprocess import call
  •   >>> call(["ls", "-l"])
  subprocess与system相比的优势是它更灵活(你可以得到标准输出,标准错误,“真正”的状态代码,更好的错误处理,等..)。我认为使用os.system已过时,或即将过时。
4. 众方法的比较以及总结
4.1. 关于 os.system
  os.system("some_command with args")将命令以及参数传递给你的系统shell,这很好,因为你可以用这种方法同时运行多个命令并且可以设置管道以及输入输出重定向。比如:
  os.system("some_command < input_file | another_command > output_file")
  然而,虽然这很方便,但是你需要手动处理shell字符的转义,比如空格等。此外,这也只能让你运行简单的shell命令而且不能运行外部程序。
4.2. 关于os.popen
  使用stream = os.popen("some_command with args")也能做与os.system一样的事,与os.system不同的是os.popen会给你一个像文件的对象从而你可以使用它来访问哪个程序的标准输入、输出。而且popen还有三个变种都是在I/O处理上有轻微不同。假如你通过一个字符串传递所有东西,你的命令会传递给shell;如果你通过一个列表传递他们,你不用担心逃避任何事。
4.3. 关于subprocess.popen
  subprocess模块的Popen类,意图作为os.popen的替代,但是因为其很全面所以比os.popen要显得稍微复杂,使用起来需要学习哦~~。
  比如你可以使用  print Popen("echo Hello World", stdout=PIPE, shell=True).stdout.read()  来替代  print os.popen("echo Hello World").read()。但是相比之下它使用一个统一的类包括4中不同的popen函数还是不错的。
4.4. 关于subprocess.call
  subprocess模块的call函数。它基本上就像Popen类并都使用相同的参数,但是它只简单的等待命令完成并给你返回代码。比如:
  return_code = subprocess.call("echo Hello World", shell=True)
  os模块中还有C中那样的fork/exec/spawn函数,但是我不建议直接使用它们。subprocess可能更加适合你。
  ===========================================
  [1] http://demi-panda.com/2013/01/25/python-shell-command/index.html
  [2] http://m.blog.csdn.net/blog/overstack/9295995
  [3] http://blog.csdn.net/swiftshow/article/details/7755543
  下面是对于文中所涉及的内容的python官方文档:
  [4] http://docs.python.org/library/subprocess.html#replacing-older-functions-with-the-subprocess-module       -- 关于使用subprocess 替代老的方法
  [5] http://docs.python.org/lib/os-process.html     -- os的exec方法族以及system方法
  [6] http://docs.python.org/lib/os-newstreams.html    -- os的popen方法
  [7] http://docs.python.org/lib/node528.html    -- os的subprocess介绍


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-558621-1-1.html 上篇帖子: shell环境设定以及bash命令行快捷键 下篇帖子: 常见Shell编程bash的内部基础命令
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表