我有一个简单的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,结果相同。
我在哪里错了?
答案 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
这样的编码路径(我通常建议使用前者)。