У меня есть сценарий оболочки, скажем, 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. Модуль readline
Python
import readline
readline.parse_and_bind("tab:complete")
file = input("Choose a file: ")
Кажется, что это почти работает, но есть одна большая проблема: он завершает только файлы в текущем каталоге пользователя. Если пользователь нажимает s<tab>
, тогда появляются src
и shared
, но если они нажимают sh<tab>
, каталоги lib
и imgs
не отображаются.
Я бы хотел какой-нибудь элегантный и простой способ добиться этого, но я уверен, что это может быть немного сложнее, чем ожидалось. Есть ли другие подходы, которые могут решить эту проблему?