【问题标题】:Linux command-line call not returning what it should from os.system?Linux 命令行调用没有从 os.system 返回它应该返回的内容?
【发布时间】:2011-04-17 00:41:19
【问题描述】:

我需要对 linux 进行一些命令行调用并从中获取返回值,但是如下所示只是返回 0,而它应该返回一个时间值,例如 00:08:19,我正在测试完全相同在常规命令行中调用它会返回时间值00:08:19,所以我对自己做错了什么感到困惑,因为我认为这是在 python 中的做法。

import os
retvalue = os.system("ps -p 2993 -o time --no-headers")
print retvalue

【问题讨论】:

  • 虽然我不会说蟒蛇,但你会想要popen。因为命令的测试输出与返回值相同...

标签: python linux python-2.7 command-line os.system


【解决方案1】:

返回的是执行该命令的返回值。您在直接执行时看到的是标准输出中命令的输出。返回 0 表示执行没有错误。

使用 popen 等来捕获输出。

沿着这条线的一些东西:

import subprocess as sub
p = sub.Popen(['your command', 'arg1', 'arg2', ...],stdout=sub.PIPE,stderr=sub.PIPE)
output, errors = p.communicate()
print output

import os
p = os.popen('command',"r")
while 1:
    line = p.readline()
    if not line: break
    print line

开启:Popen and python

【讨论】:

    【解决方案2】:

    如果你只对流程的输出感兴趣,使用 subprocess'check_output 函数是最简单的:

    
    output = subprocess.check_output(["command", "arg1", "arg2"]);
    

    然后输出将程序输出保存到标准输出。查看上面的链接了解更多信息。

    【讨论】:

    • 也推荐,如果你不需要输出,subprocess.check_call(),它检查进程状态并在失败时引发错误。 (2.4+) 但这不是 this 问题的答案,它特别需要捕获输出。不过,我的最爱之一。 :)
    【解决方案3】:

    最简单的方法是这样的:

    import os
    retvalue = os.popen("ps -p 2993 -o time --no-headers").readlines()
    print retvalue
    

    这将作为列表返回

    【讨论】:

      【解决方案4】:

      如果传递的命令执行成功,您的代码将返回0,如果失败则返回非零。以下程序适用于python2.7,已检查3及以上版本。试试这个代码。

      >>> import commands
      >>> ret = commands.getoutput("ps -p 2993 -o time --no-headers")
      >>> print ret
      

      【讨论】:

      • commands.getoutput('ls') 为我抛出“Usage: commands [bnum]”错误。
      • 这个模块在 Python 3 中被移除了,很可惜,因为它比 suprocess 模块更方便。
      【解决方案5】:

      是的,它违反直觉并且看起来不是很 Python,但它实际上只是模仿了 unix API 设计,其中这些调用是 C POSIX 函数。检查man 3 popen && man 3 system

      sn-p 替换我使用的 os.system 更方便一些:

      from subprocess import (PIPE, Popen)
      
      
      def invoke(command):
          '''
          Invoke command as a new system process and return its output.
          '''
          return Popen(command, stdout=PIPE, shell=True).stdout.read()
      
      
      result = invoke('echo Hi, bash!')
      # Result contains standard output (as you expected it in the first place).
      

      【讨论】:

        【解决方案6】:

        我无法向 IonicBurger 添加评论,因为我没有“50 声望”所以 我将添加一个新条目。我很抱歉。 os.popen() 最适合用于多个/复杂的命令(我的观点),并且除了像以下更复杂的多个命令一样获取标准输出之外,还用于获取返回值:

        import os
        out = [ i.strip() for i in os.popen(r"ls *.py | grep -i '.*file' 2>/dev/null; echo $? ").readlines()]
        print "     stdout: ", out[:-1]
        print "returnValue: ", out[-1]
        

        这将列出所有名称中包含单词'file'的所有python文件。 [...] 是一个列表推导,用于从每个条目中删除(剥离)换行符。 echo $? 是一个 shell 命令,用于显示最后执行的命令的返回状态,该命令将是 grep 命令和本示例中列表的最后一项。 2>/dev/null 表示将 grep 命令的 stderr 打印到 /dev/null 所以它没有出现在输出中。 'ls' 命令之前的 'r' 是使用原始字符串,因此 shell 不会错误地解释像 '*' 这样的元字符。这适用于 python 2.7。这是示例输出:

              stdout:  ['fileFilter.py', 'fileProcess.py', 'file_access..py', 'myfile.py']
         returnValue:  0
        

        【讨论】:

          【解决方案7】:

          这是一个旧线程,但纯粹使用os.system,以下是访问ps 调用返回的数据的有效方法。注意:它确实使用管道将数据写入磁盘上的文件。 并且 OP 并没有特别要求使用os.system 的解决方案。

          >>> os.system("ps > ~/Documents/ps.txt")
          0    #system call is processed.
          >>> os.system("cat ~/Documents/ps.txt")
            PID TTY          TIME CMD
           9927 pts/0    00:00:00 bash
          10063 pts/0    00:00:00 python
          12654 pts/0    00:00:00 sh
          12655 pts/0    00:00:00 ps
          0
          

          因此,

          >>> os.system("ps -p 10063 -o time --no-headers > ~/Documents/ps.txt")
          0
          >>> os.system("cat ~/Documents/ps.txt")
          00:00:00
          0
          

          不知道为什么它们都返回零。

          【讨论】:

          • 返回的零是退出代码,表示命令执行成功
          【解决方案8】:

          对于您的要求,子进程 python 模块的 Popen 函数就是答案。例如,

          import subprocess
          ..
          process = subprocess.Popen("ps -p 2993 -o time --no-headers", stdout=subprocess.PIPE, stderr=subprocess.PIPE)
          stdout, stderr = process.communicate()
          print stdout
          

          【讨论】:

            【解决方案9】:

            好吧,我相信这是最快的方式

            import os
            print(os.popen('command').readline())
            x = _
            print(x)
            

            【讨论】:

            • print(os.popen('command').read()) 如果要返回所有输出。 readline 只会返回第一行。另外值得注意的是,这是 Python3 语法。
            • _ 只在python交互shell中设置;这在脚本中不起作用。
            【解决方案10】:
            using commands module
            import commands
            """ 
            Get high load process details 
            """
            result = commands.getoutput("ps aux | sort -nrk 3,3 | head -n 1")
            print result  -- python 2x
            print (result) -- python 3x 
            

            【讨论】:

              猜你喜欢
              • 2019-04-27
              • 1970-01-01
              • 2022-11-03
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多