2017-11-30 4 views
0

실행하기 위해 몇 가지 인수가 필요한 스크립트를 만들었습니다. 원래 'auto'인수를 사용하여 자동으로 실행할 수 있지만, 데몬으로 지정된 인수를 사용하여 스크립트를 실행하도록 데몬스트레이션하려고합니다. 문제는 python-daemon과 argparse가 누가 누가 무엇을 파싱할지 결정할 때 오지 않는 것입니다.python-daemon + argparse?

[email protected]:~# ./pyfilter.py start 
ERROR: File 'start' not found # argparse parsed 'start' accidentally 

[email protected]:~# ./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 

[email protected]:~# ./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' 

파이썬 데몬 또는 무언가에 '시작'인수를 통과 할 수있을 것인가 :

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() 

여기에 내가이 작품을 만들기 위해 노력했습니다 명령이야? 또는 argparsing을 제거 할 수 있다면 괜찮을 것이지만 'file'인수는 필수 항목입니다.

+0

'argparse'는'sys.argv에 [0]'(도움)은'prog' 이름을 사용하고 (디폴트로) 나머지를 구문 분석합니다. 그러나 문자열 목록을 줄 수 있습니다. 함수에'parser'를 패키지하는 것은 좋은 습관이며'if __name__' 블럭으로부터'parse_args' 호출 만하십시오. 이렇게하면 (가져 오기와 반대되는 스크립트에서) 언제 사용되는지 제어 할 수 있습니다. – hpaulj

답변

0

Argparse는 기본적 당 sys.argv에에서 인수 (here 참조)합니다. 당신이 단지 기본 인자를 가진 경우 parse_args 함수를 호출 당신이 여기에서 보는 행동이, 을 일어나는 것은 놀라운 일이 아니다. sys.argv 대신 구문 분석 할 내용을 전달할 수 있습니다.

는 예를 들어 this question를 참조하십시오.

그래서 python-deamon에 필요한 모든 것을 소비 한 다음 나머지 args를 argparse로 구문 분석하십시오.

+0

나는이 질문을 읽었으며 첫 번째 논의를 생략하면 좋은 해결책이 될 것이라고 생각하지만, 어떻게 완료되었는지는 이해할 수 없다. 내 스크립트의 맨 위에 "argv = sys.argv [1 :]"을 입력 한 다음 "args = parser.parse_args (argv)"를 실행했지만 작동하지 않습니다. 이제 argparse는 'start'다음에 오는 파일 인수를 작업 인수로 인식합니다. 나는 이것이 나의 argparsing에게 모든 인수에 대해 1 오프셋을 주었다고 가정하고있다. 또한, 시작은 (데몬 인수가 지정) 즉 다른 질문 –

+0

내가 방금 sys.argv에를받을 수 있도록 관련된 발명 조정해야 할 수도 있습니다 생각 비록 나는 액션 인수의 요구 사항을 생략 할 수 있도록하고 싶습니다 지정된 경우 손으로 요구에 맞춘 다음 parse_args에 결과가 무엇이든 피드하십시오. – RunOrVeith