当脚本由cron运行时,subprocess.call总是返回错误

时间:2019-06-14 11:17:10

标签: python subprocess

我有一个简单的python脚本,可用于自动更新dhcp配置文件。

想法是,它将新的配置文件放入dhcpd目录中,然后运行检查,如果返回确定,则可以重新启动服务。我的代码如下:


syslog.syslog(syslog.LOG_INFO, 'INFO: file copied to /etc/dhcp/conf.d')
return_code = subprocess.call(['dhcpd -t -cf /etc/dhcp/dhcpd.conf'], shell=True)
if return_code != 0:
    print('dhcp config test failed, exiting script')
    syslog.syslog(syslog.LOG_ERR, 'ERROR: dhcp config test failed, exiting script')
    sys.exit()
else:
    print('dhcp config test passed restarting service')
    syslog.syslog(syslog.LOG_INFO, 'INFO: config check passed, restarting service')
    return_code = subprocess.call(['service', conf['service_name'], 'restart'])
    if return_code != 0:
        print('dhcpd service failed to restart')
        syslog.syslog(syslog.LOG_ERR, 'ERROR: dhcpd service failed to restart')
    else:
        print('dhcpd service restarted')
        syslog.syslog(syslog.LOG_INFO, 'INFO: service restarted')
        email_results()

此脚本由cron作业启动,运行时始终会在以下位置失败:

print('dhcp config test failed, exiting script')

如果我手动运行脚本,它将始终运行正常,并按预期继续进行到最后。

如果我打开python shell并手动运行重要命令,它似乎可以正常工作:

python3
Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> return_code = subprocess.call(['dhcpd -t -cf /etc/dhcp/dhcpd.conf'], shell=True)
Internet Systems Consortium DHCP Server 4.3.3
Copyright 2004-2015 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/
Config file: /etc/dhcp/dhcpd.conf
Database file: /var/lib/dhcp/dhcpd.leases
PID file: /var/run/dhcpd.pid
>>> print(return_code)
0

我尝试使用“ shell = True”,也尝试不使用。 我也尝试过subprocess.check_call,结果相同。

我在哪里错了?

2 个答案:

答案 0 :(得分:1)

在脚本中使用绝对路径而不是仅使用诸如dhcpd之类的命令名称。

尝试在设置为空的PATH后调用脚本时,脚本是否仍然可以工作。

答案 1 :(得分:1)

subprocess的参数应为字符串数组或单个字符串。传递单个字符串的数组是一个错误,尽管它可能会在某些从根本上被破坏的平台上正常工作。

你想要

return_code = subprocess.call(['dhcpd', '-t', '-cf', '/etc/dhcp/dhcpd.conf'])   # shell=False implicitly

return_code = subprocess.call('dhcpd -t -cf /etc/dhcp/dhcpd.conf', shell=True)

但实际上,您应尽可能避免使用shell=True;另请参见Actual meaning of 'shell=True' in subprocess

当然,如果dhcpd不在您从PATH获得的cron中,则您想相应地更新PATH,或使用显式的硬式-像/usr/sbin/dhcpd这样的编码路径(我通常建议使用前者)。