如何在终端中制作 Python 脚本“tab-complete”目录?

Posted

技术标签:

【中文标题】如何在终端中制作 Python 脚本“tab-complete”目录?【英文标题】:How to make a Python script "tab-complete" directories in terminal? 【发布时间】:2019-09-30 19:36:51 【问题描述】:

我有一个 Shell 脚本,比如说run.sh,它从键盘读取用户输入,然后执行一些特定任务。由于某些技术原因,我将此脚本迁移到 Python,例如 run.py,以实现完全相同的目标。

run.sh 文件中,我向用户询问输入,该输入通常是文件系统中的一个文件,因此我提供了“制表符完成”的选项,并通过以下行简单地实现了它:

read -e -p "Choose a file: " file

-e 标志的作用是完成用户输入的制表符。例如,如果用户的当前目录是project,则遵循以下结构:

project
-- src
-- shared
   -- lib
   -- imgs
      -- image.png
-- include
-- README.txt

输入文件是image.png,他们可以按如下方式进行:

sh<tab>i<tab><tab>

结果将是shared/imgs/image.png

现在我如何在 Python 脚本中实现它?您可能认为有大量相关问题,但我无法在run.py 中重现完全相同的结果。

到目前为止我所尝试的:

1. Python 的os 模块:

import os

os.system("read -e -p 'Choose a file:'")

输出:sh: 1: read: Illegal option -e

2。 Python 的subprocess 模块

import subprocess

subprocess.run(['read', '-e', '-p', 'Choose a file'])

输出:

Traceback (most recent call last):
  File "run.py", line 26, in <module>
    subprocess.run(['read', '-e', '-p', 'Choose a file'])
  File "/usr/lib/python3.7/subprocess.py", line 453, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.7/subprocess.py", line 756, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.7/subprocess.py", line 1499, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'read': 'read'

3. Python的readline模块

import readline

readline.parse_and_bind("tab:complete")
file = input("Choose a file: ")

这似乎几乎可以工作,但有一个大问题:它只完成用户当前目录中的文件。如果用户点击s&lt;tab&gt;,则srcshared 会出现,但如果他们点击sh&lt;tab&gt;libimgs 目录不会出现。

我想要一些优雅而简单的方法来实现这一点,但我相信这可能比预期的要困难一些。有没有其他方法可以解决这个问题?

【问题讨论】:

您的尝试 #1 和 #2 失败的原因是 read 是 shell 内置命令,而不是磁盘上的实际可执行文件。 (它必须是内置的,否则它无法使用其结果设置 shell 变量。) 【参考方案1】:

设置合理的完成分隔符:

import readline

readline.set_completer_delims(' \t\n=')
readline.parse_and_bind("tab: complete")
option = input("Tab complete a file: ")

默认情况下,readline 将根据以下任何一项进行分隔:

>>> import readline
>>> readline.get_completer_delims()
' \t\n`~!@#$%^&*()-=+[]\\|;:\'",<>/?'

由于/ 是该集合的一部分,/ 之后的任何内容都将独立于其之前的任何内容完成。当您尝试完成文件路径时,这显然没有意义。

【讨论】:

谢谢,这正是我想要的。还要访问带有空格的文件,我设置了readline.set_completer_delims('\t\n=')

以上是关于如何在终端中制作 Python 脚本“tab-complete”目录?的主要内容,如果未能解决你的问题,请参考以下文章

如何制作 Mac 终端弹出/警报?苹果脚本?

如何在 Pycharm 终端中使用 python-evtx 库运行脚本? [复制]

如何在Unity中执行Python脚本后让其终端自行关闭

如何在 bash 中制作聊天脚本?

如何在 Linux 中使用终端命令将文件参数传递给我的 bash 脚本? [复制]

如何从类似于 pip 或 howdoi 命令的任何终端实例将 python 脚本作为全局命令运行?