【问题标题】:python-daemon + argparse?python守护进程+ argparse?
【发布时间】:2018-05-14 13:47:39
【问题描述】:

我制作了一个需要几个参数来运行的脚本。最初它可以使用参数“auto”自动运行,但我正在尝试对其进行守护进程,以便它将使用指定参数作为守护进程运行脚本。问题是在决定谁解析什么时,python-daemon 和 argparse 似乎并不一致。

parser = argparse.ArgumentParser(usage='pyfilter.py <file> <options> <actions>')
parser.add_argument('file', help='blacklist file containing IPs', type=str)

subparsers = parser.add_subparsers(help='help', dest='action')

parser_update = subparsers.add_parser('update', help='update help')
parser_update.add_argument('-c', '--check', help="check IPs for abuse reports", dest="check", type=str, nargs=1)

parser_blacklist = subparsers.add_parser('blacklist', help='create iptables rules for malicious IPs specified'
                                                           'in the provided file')
parser_clear = subparsers.add_parser('clear', help='clear iptables')

parser_auto = subparsers.add_parser('auto', help='automatically run update and blacklist on a loop')
parser_auto.add_argument('-i', '--interval', help='specify the loop interval', dest='interval', type=int, nargs=1)
parser_auto.add_argument('-c', '--check', help="check IPs for abuse reports", dest="check", type=str, nargs=1)

parser.add_argument('-p', '--port', help='specify the port to block', type=int)
parser.add_argument('-v', '--verbose', help='write output to screen', nargs=1)
args = parser.parse_args()

. . .

class pyfilterDaemon():
    def __init__(self):
        self.stdin_path = '/dev/null'
        self.stdout_path = '/dev/tty'
        self.stderr_path = '/dev/tty'
        self.pidfile_path = '/tmp/pyfilter.pid'
        self.pidfile_timeout = 5

    def run(self):
        while True:
            update()
            blacklist()
            time.sleep(interval)
. . .

def main():
    #handle()
    d = pyfilterDaemon()
    daemon_runner = runner.DaemonRunner(d)
    daemon_runner.start()

这是我尝试使用的命令:

root@tfof:~# ./pyfilter.py start
ERROR: File 'start' not found  # argparse parsed 'start' accidentally

root@tfof:~# ./pyfilter.py /etc/blacklist.lst -v yes auto
usage: checkfilter.py stop|restart|start  # now the argparse arguments are satisfied, but python-daemon is looking for its argument

root@tfof:~# ./pyfilter.py /etc/blacklist.lst -v yes auto start
usage: pyfilter.py <file> <options> <actions>
pyfilter.py: error: unrecognized arguments: start  # argparse is trying to parse 'start'

是否可以将“开始”参数传递给 python-daemon 或其他东西?或者,如果我可以摆脱 argparsing 就好了,但 'file' 参数是必须的。

【问题讨论】:

  • argparse 使用sys.argv[0] 作为prog 名称(用于帮助),并解析其余部分(作为默认值)。但是你可以给它任何字符串列表。将parser 打包到一个函数中也是一种很好的做法,并且只在if __name__ 块中调用parse_args。这样您就可以控制何时以及是否使用它(在脚本中而不是在导入中)。

标签: python argparse python-daemon


【解决方案1】:

Argparse 默认从 sys.argv 获取参数(请参阅here)。 你在这里看到的行为正在发生并不奇怪, 因为您只需使用默认参数调用 parse_args 函数。 你可以只传递你想要解析的任何东西,而不是 sys.argv。

有关示例,请参阅 this question

因此,使用 python-deamon 所需的任何内容,然后使用 argparse 解析剩余的 args。

【讨论】:

  • 我已经阅读了这个问题,我认为省略第一个参数是一个很好的解决方案,但是我不明白它是如何完成的。在我的脚本顶部,我输入了“argv = sys.argv[1:]”,然后完成了“args = parser.parse_args(argv)”,但是它不起作用。现在 argparse 正在将 'start' 之后的文件参数识别为操作参数。我假设这为我的 argparsing 提供了所有参数的 1 个偏移量。此外,如果指定了启动(指定了守护程序参数),我希望能够省略操作参数的要求,尽管这是一个不同的问题
  • 我认为您可能只需要获取 sys.argv 并根据您的需要手动调整它,然后将结果提供给 parse_args。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-21
  • 2017-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多