如何在终端中将Python脚本设置为“制表符完整”目录?

时间:2019-05-13 20:03:58

标签: python python-3.x shell terminal subprocess

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

run.sh文件中,我要求用户输入一个文件,通常是文件系统中的一个文件,因此我选择了“制表符补全”,并通过以下行简单地实现了它:< / p>

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<tab>,则显示srcshared,但是如果用户点击sh<tab>,则libimgs目录不会显示。

我想要一些优雅而简单的方法来实现这一目标,但是我坚信这可能比预期的要困难一些。还有其他方法可以解决此问题吗?

1 个答案:

答案 0 :(得分: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`~!@#$%^&*()-=+[{]}\\|;:\'",<>/?'

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