如何在Python中优雅地执行此操作?

时间:2014-01-22 03:55:33

标签: bash shell python ruby

我只是在学习Python。我希望使用Python的一件事是Linux shell脚本。我一直在研究一些例子,并通过将我的bash脚本转换为Python来练习。

我花了几个小时将我的一个bash脚本转换为Python,我对结果代码感到非常失望。它更冗长,语法更混乱。它肯定不像我开始时的bash脚本那样简洁明了。

然后我偶然发现了这个(无关的)Ruby脚本。哇。它似乎可以直接访问shell,不像Python在语言和shell之间有一层或两层。

#! /usr/bin/ruby
MAX_TIME_SINCE_START = 1800
begin
  curr_time = Time.new.to_i
  kslideshow_processes_list = `pgrep kslideshow.kss`.split("\n")
  kslideshow_processes_list.each { |kslideshow_process|
      kslideshow_process.strip!
      ps_result = `ps -p #{kslideshow_process} -o lstart`
      process_start_date = `ps -p #{kslideshow_process} -o
lstart`.split("\n")[1].strip
      get_date_command = "date -d \"#{process_start_date}\" +\"%s\""
      kslideshow_start_time = `#{get_date_command}`.to_i
      time_since_started = curr_time - kslideshow_start_time
      if time_since_started MAX_TIME_SINCE_START
          system( "kill #{kslideshow_process}" )
      end
  }
  sleep MAX_TIME_SINCE_START
end while true

这是我希望从bash脚本切换到Python的代码。在Python中是否可以如此干净地编写shell脚本?

对于我来说,看到上面的代码被知道他们正在做什么的人转换为Python会非常有教育意义。

我不打算开始Ruby与Python的讨论。我只是想看看上面的任务是如何干净地由Python知道更多的人在Python中实现的。这个网站是一个公平的问题吗?感谢

2 个答案:

答案 0 :(得分:2)

使用plumbum包,您可以通过IMO至少像在Ruby中一样优雅。有一些方法可以优化系统调用(例如使用dateutils转换日期格式,或使用psutils),但这不再是调用系统实用程序的比较(我希望我得到了来自Ruby示例的逻辑正确):

from time import time, sleep
from plumbum.cmd import pgrep, ps, date, kill

MAX_TIME_SINCE_START = 5 # 1800

while True:
   curr_time = time()
   for kslideshow_process in pgrep("gimp").split():
      print kslideshow_process
   process_start_date = ps("-p",  kslideshow_process, "-o", "lstart"
                           ).split("\n")[1].strip()
   kslideshow_start_time = int(date("-d", process_start_date, '+%s'))
   print kslideshow_start_time
   time_since_started = curr_time - kslideshow_start_time
   if time_since_started > MAX_TIME_SINCE_START:
      kill([kslideshow_process])
   sleep(MAX_TIME_SINCE_START)

您可以使用from plumbum.cmd import ...导入任何命令行程序,它会自动作为将命令行参数作为参数的函数提供。 您还可以创建命令链:

chain = ls["-a"] | grep["-v", "\\.py"] | wc["-l"]
result = chain()

因此,很少需要中间变量将结果从一个子shell传递到另一个子shell。

答案 1 :(得分:1)

除了糟糕的想法和方法,你可以捅自己的眼睛..在python中打开另一个进程的更有效方法的一个例子如下......


process = subprocess.Popen([MyCommand, parameter1, "parameter 2"], shell=False, stdout=subprocess.PIPE,
                                              stderr=subprocess.PIPE, stdin=subprocess.PIPE)
stdout,stderr = process.communicate()
return_code = process.poll()

使用popen进行操作比其他语言稍微增加一些,但是它提供了很多功能,我所知道的其他任何脚本语言都没有提供,例如从许多进程中获取输出。