python – 如何为我在pty下运行的进程设置终端前台进程组?

python – 如何为我在pty下运行的进程设置终端前台进程组?,第1张

概述我写了一个简单的包装脚本,用于在它们失败时重复命令,称为 retry.py.但是,由于我想看到子命令的输出,我不得不拉一些pty技巧.这适用于像rsync这样的程序,但是像scp这样的其他程序会应用额外的测试来显示像进度表这样的东西. scp代码有一个广泛的测试: getpgrp() == tcgetpgrp(STDOUT_FILENO); 当我运行包装器脚本时,这会失败.正如您在我的简单tty_ 我写了一个简单的包装脚本,用于在它们失败时重复命令,称为 retry.py.但是,由于我想看到子命令的输出,我不得不拉一些pty技巧.这适用于像rsync这样的程序,但是像scp这样的其他程序会应用额外的测试来显示像进度表这样的东西.

scp代码有一个广泛的测试:

@H_419_4@getpgrp() == tcgetpgrp(STDOUT_fileNO);

当我运行包装器脚本时,这会失败.正如您在我的简单tty_test.c测试用例中看到的:

@H_419_4@./tty_testsisatty reports 1pgrps are 13619 and 13619

和:

@H_419_4@./retry.py -v -- ./tty_testscommand is ['./tty_tests']isatty reports 1pgrps are 13614 and -1child finished: rc = 0Ran command 1 times

我已经尝试使用tcsetpgrp(),最终作为pty fd的IOCTL,但这导致了ptys的-EINVAL.如果可能的话,我宁愿继续使用Python子进程机器,还是需要手动fork / execve’ing?

解决方法 如果您不需要为子流程提供全新的pty,我相信您可以将程序削减到此: @H_419_4@from argparse import ArgumentParserimport osimport signalimport subprocessimport itertools# your argumentparser stuff goes heredef become_tty_fg(): os.setpgrp() hdlr = signal.signal(signal.SIGTTOU,signal.SIG_IGN) tty = os.open('/dev/tty',os.O_RDWR) os.tcsetpgrp(tty,os.getpgrp()) signal.signal(signal.SIGTTOU,hdlr)if __name__ == "__main__": args = parser.parse_args() if args.verbose: print "command is %s" % (args.command) if args.invert and args.limit==None: sys.exit("You must define a limit if you have inverted the return code test") for run_count in itertools.count(): return_code = subprocess.call(args.command,close_fds=True,preexec_fn=become_tty_fg) if args.test == True: break if run_count >= args.limit: break if args.invert and return_code != 0: break elif not args.invert and return_code == 0: break print "Ran command %d times" % (run_count)

setpgrp()调用在同一会话中创建一个新进程组,以便新进程将从用户接收任何ctrl-c / ctrl-z / etc,而您的重试脚本则不会.然后tcsetpgrp()使新进程组成为控制tty上的前一个进程组.当发生这种情况时,新进程会获得一个SIGTTOU(因为自setpgrp()以来,它一直在后台进程组中),这通常会使进程停止,因此这是忽略SIGTTOU的原因.我们将SIGTTOU处理程序设置回原来的状态,以最大限度地减少子进程被意外信号表混淆的可能性.

由于子进程现在位于tty的前台组中,因此其tcgetpgrp()和getpgrp()将相同,并且isatty(1)将为true(假设它从retry.py继承的stdout实际上是tty).您不需要在子进程和tty之间代理流量,这样您就可以放弃所有选择事件处理和fcntl-nonblocking-setting.

总结

以上是内存溢出为你收集整理的python – 如何为我在pty下运行的进程设置终端前台进程组?全部内容,希望文章能够帮你解决python – 如何为我在pty下运行的进程设置终端前台进程组?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1207026.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存