如何执行带有许多参数的python subprocess.Popen?

时间:2017-10-24 03:41:48

标签: python linux redhat

我需要在本地和远程服务器上执行相同的命令。所以我正在使用subprocess.Popen来执行,并且本地命令按预期工作,但是当我在远程执行时它会给我一些错误,比如找不到命令。我很感谢你的支持,因为我是新手。

本地执行功能

    def topic_Offset_lz(self):
         CMD = "/dsapps/admin/edp/scripts/edp-admin.sh kafka-topic offset %s -e %s | grep -v Getting |grep -v Verifying | egrep -v '^[[:space:]]*$|^#' | awk -F\: '{print $3}'|sed '%sq;d'" % (self.topic,self.envr,self.partition)
         t_out_lz, t_error_lz = subprocess.Popen(CMD, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
         return t_out_lz

远程服务器执行

    def topic_offset_sl(self):
         CMD = "/dsapps/admin/edp/scripts/edp-admin.sh kafka-topic offset %s -e %s | grep -v Getting |grep -v Verifying | egrep -v '^[[:space:]]*$|^#' | awk -F\: '{print $3}'|sed '%sq;d'" % (self.topic, self.envr, self.partition)
         t_out_sl, t_error_sl = subprocess.Popen(["ssh", "-q", CMD], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
         return t_error_sl

我正在获取远程执行错误

  

着陆区偏移:0

     

SoftLayer Zone Offset:/ bin / sh:^#| sed 1:找不到命令   / bin / sh:d:找不到命令

2 个答案:

答案 0 :(得分:0)

ssh命令将其参数向量作为单个命令行字符串传递,而不是数组。为此,它只是连接参数,而不执行shell引用:

$ ssh target "python -c 'import sys;print(sys.argv)'" 1 2 3
['-c', '1', '2', '3']
$ ssh target "python -c 'import sys;print(sys.argv)'" "1 2 3"
['-c', '1', '2', '3']

如果有适当的shell引用,1 2 3"1 2 3"之间的区别将被保留,第一个参数不需要双引号。

无论如何,在您的情况下,以下内容可能有效:

def topic_offset_sl(self):
     CMD = "ssh -q " + pipes.quote("/dsapps/admin/edp/scripts/edp-admin.sh"
             + " kafka-topic offset %s -e %s" % (self.topic, self.envr)) \
         + "grep -v Getting |grep -v Verifying | egrep -v '^[[:space:]]*$|^#'"
         + " | awk -F\: '{print $3}'|sed '%sq;d'" % self.partition
     t_out_sl, t_error_sl = subprocess.Popen(CMD], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
     return t_error_sl

这假设您只想远程运行/dsapps/admin/edp/scripts/edp-admin.sh脚本而不是其余脚本。

请注意,使用字符串拼接构建命令行的方式可能会引入shell命令注入漏洞(本地和远程服务器上)。

答案 1 :(得分:0)

我提出了以下解决方案,可能会有简单的方法,而不是这个。

 def topic_offset_sl(self):
        CMD_SL1 = "ssh -q %s '/dsapps/admin/edp/scripts/edp-admin.sh kafka-topic offset %s -e %s'" % (KEY_SERVER,self.topic, self.envr)
        CMD_SL2 = "| grep -v Getting |grep -v Verifying | egrep -v '^[[:space:]]*$|^#' | awk -F\: '{print $3}'|sed '%sq;d'" % (self.partition)
        t_out_sl, t_error_sl = subprocess.Popen(CMD_SL1 + CMD_SL2 , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate()
        return t_out_sl