在python中使用subprocess.popen无法将shell命令输出重定向到文件

tp5buhyn  于 2021-06-26  发布在  Hive
关注(0)|答案(3)|浏览(722)

我使用的是Python2.6.6,无法使用“>”将直线(hive)sql查询输出重新定向到unix上的一个文件中,该输出返回多行。为了简单起见,我在当前目录上用简单的“ls”命令替换了sql查询并输出到文本文件。
请忽略sendfile函数的语法。我想帮助调整函数“callcmd”以将stdout管道传输到文本文件。

def callcmd(cmd, shl):
    logging.info('> '+' '.join(map(str,cmd)))
    #return 0;
    start_time = time.time()
    command_process = subprocess.Popen(cmd, shell=shl, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
    command_output = command_process.communicate()[0]
    logging.info(command_output)
    elapsed_time = time.time() - start_time
    logging.info(time.strftime("%H:%M:%S",time.gmtime(elapsed_time))+' = time to complete (hh:mm:ss)')
    if (command_process.returncode != 0):
        logging.error('ERROR ON COMMAND: '+' '.join(map(str,cmd)))
        logging.error('ERROR CODE: '+str(ret_code))
    return command_process.returncode

cmd=['ls', ' >', '/home/input/xyz.txt']
ret_code = callcmd(cmd, False)
lf5gs5x2

lf5gs5x21#

这里,命令输出中的标准输出被写入一个文件。您不需要使用任何重定向,尽管另一种方法可能是将python打印到stdout,然后在shell中将其重定向到一个文件。


# !/usr/bin/python

import subprocess

cmd=['ls']  

command_process = subprocess.Popen(
cmd,
shell='/bin/bash',
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True
)

command_output = command_process.communicate()[0]

if (command_process.returncode != 0):
  logging.error('ERROR ON COMMAND: '+' '.join(map(str,cmd)))
  logging.error('ERROR CODE: '+str(ret_code))

f = open('listing.txt','w')
f.write(command_output)
f.close()
kadbb459

kadbb4592#

我将这段代码添加到我的代码中,它运行良好。感谢@snohdo

f = open('listing.txt','w')
f.write(command_output)
f.close()
tv6aics1

tv6aics13#

你的命令(即。 cmd )可能是 ['sh', '-c', 'ls > ~/xyz.txt'] . 这意味着 ls 不会传递给python,它完全发生在派生的shell中,因此无法记录输出。如果那样的话,我会用 return_code = subprocess.call(cmd) ,不需要 Popen 以及 communicate .
等价地,假设您使用bash或类似的工具,您可以简单地使用

subprocess.call('ls > ~/test.txt', shell=True)

如果您想访问输出,例如日志记录,您可以使用

s = subprocess.check_output(['ls'])

然后像用python一样将其写入一个文件。要检查非零退出代码,请处理 CalledProcessError 在这种情况下提出的。

相关问题