如何让 argparse 为具有两个名称的 python 脚本显示一个帮助页面?

How do I get argparse to show one help page for a python script with two names?

我当前的工作 python 脚本使用 getopts,因为它是对使用 Getopt::Long 的 perl 脚本的重写。我想迁移到 argparse,但失败了,因为这些选项不太适合 argparse 的工作方式。

然后我有了一个好主意 [?],如果我的脚本有 2 个名称怎么办,例如:foo-ssh 和 foo-rsync

并将 foo-rsync 符号链接到 foo-ssh(超过 90% 的脚本是 foo-ssh,rsync 选项是一个附加组件,不适合作为选项),然后将代码放在脚本仅处理其 运行 下的特定名称的选项。

我知道子解析器,但它看起来并不完全像我正在寻找的那样,并且产生了比我开始时更加丑陋和混乱的帮助输出。

如果我尝试尽可能接近 argparse 的 getopts 方式,我会得到这个:

usage: foo-ssh [-h] [--version] [--debug] [--forward-agent HOST:PORT]
                [--ipv4] [--knock HOST:PORT]
                [--libvirt-vnc HOST:PORT | --rsync]
                [USER@]HOST

哪个是错的,哪个是对的,就是不对。

来自 perl 脚本帮助页面:

Usage: foo-ssh <options> [USER@]HOST
       foo-ssh <options> --knock HOST:PORT [USER@]HOST
       foo-ssh <options> --libvirt-vnc HOST:PORT [USER@]HOST
       foo-ssh <options> --rsync -- <rsync options> [USER@]HOST:/path/file.name /tmp

我想要什么:

usage: foo-ssh [-h] [--version] [--debug] [--forward-agent HOST:PORT]
                [--ipv4] [--knock HOST:PORT] 
                [--libvirt-vnc HOST:PORT]
                [USER@]HOST
       foo-rsync [OPTION...] [USER@]HOST:SRC... [DEST]
       foo-rsync [OPTION...] SRC... [USER@]HOST:DEST

首先,我在这里是在打死马吗?如果我用相同数量或更多的代码来替换已经工作的代码,那么整个练习就毫无意义。

其次,这可能吗?我正在寻找什么来实现它?

脚注:未包含 Perl 代码示例,因为它写得像河马用自己的便便标记它的领地(即:到处都是),这是重写的原因之一。

检查 sys.argv[0] 的值以查看调用脚本的名称,然后构建适当的 ArgumentParser 作为响应。

if sys.argv[0].endswith("foo-ssh"):
    parser = ArgumentParser(epilog="For rsync, run foo-rsync")
    parser.add_argument(...)
    ...
elif sys.argv[0].endswith("foo-rsync"):
    parser = ArgumentParser(epilog="For ssh, run foo-ssh")
    parser.add_argument(...)
else:
    sys.exit("Must be invoked as foo-ssh or foo-rsync, not {}".format(sys.argv[0]))

args = parser.parse_args()

(如果 epilog 会下降 "below the fold",请将对其他脚本的引用放在 description 中。)