고정 디렉터리에 루트가 있는 하위 디렉터리와 하위 디렉터리를 "자동 완성"하고 싶습니다.

고정 디렉터리에 루트가 있는 하위 디렉터리와 하위 디렉터리를 "자동 완성"하고 싶습니다.

음악 파일이 포함된 디렉터리가 몇 개 있습니다.

$ tree -d ~/Music/
/home/boffi/Music/
├── Aldous_Harding
│   ├── Aldous_Harding
│   ├── Designer
│   ├── Party
│   └── Warm_Chris
├── Madness
│   └── The_Very_Best
└── Mitski
    ├── Be_the_Cowboy
    ├── Bury_Me_At_Makeout_Creek
    ├── Laurel_Hell
    ├── Lush
    ├── Puberty_2
    ├── Retired_from_Sad,_New_Career_in_Business
    └── The_Land_Is_Inhospitable_and_So_Are_We

그리고 스크립트

$ cat ~/bin/pmd
# Play Music Directories

root=/home/boffi/Music/
list_of_dirs=""
for dir in $@ ; do
  list_of_dirs=${list_of_dirs}" ${root}$dir"
done
list_of_files=$( find ${list_of_dirs} | shuf )
echo mpv -no-terminal -no-video ${list_of_files}
$

완성 기능을 사용 하면 cd ~/Music명령이 예상대로 작동합니다. 범용 디렉터리에서 실행하면 완료 기능이 명령줄에 전체 경로 이름을 입력하기 때문에 작동하지 않습니다.

~/Music명령줄에 전체 경로 이름을 입력하지 않고 루트로 디렉터리/하위 디렉터리를 완료하도록 bash/readline을 어떻게 설득할 수 있나요 ?


내가 읽고폴더의 자동 완성 명령그리고 Bash 자동 완성: 다른 디렉터리의 파일 및 디렉터리 나열.

첫 번째 경우 명령은 단일 인수를 사용하고 두 번째 경우 전체 경로 이름은 명령줄에 배치되며 하위 디렉터리에서는 수행할 수 없습니다.

조언을 따르다댓글에서 제안한 내용을 구현했습니다.여기, 그러나 완료되면 pmds내 시스템의 모든 실행 파일이 나열되고 어쨌든 명령을 실행하면 다음으로 이동됩니다.~/Music

$ pwd
/home/boffi
$ tail -3 .bashrc
alias yt="yt-dlp -f 'bestvideo[height<=?720]+bestaudio/best' -write-sub --write-auto-sub --sub-lang 'en.*' -o"

. /home/boffi/script
$ cat script
#!/usr/bin/bash

pmds () { echo /home/boffi/Music/$1 ; }
goM ()  { cd /home/boffi/Music ; }
complete -s -F goM pmds

$ . .bashrc
$ pmds <TAB>
Display all 6241 possibilities? (y or n)
$ pmds pippo
/home/boffi/Music/pippo
$ pwd
/home/boffi/Music
$ 

답변1

한 번 시도해 보세요. 더 쉬운 방법이 있습니다 complete -C. 를 사용하여 디렉터리 이름을 작성하여 출력을 완료하는 함수를 정의하세요.

_pmd () {
  shopt -s nullglob
  cd /home/boffi/Music
  # $2 is the word being completed
  printf "%s\n" "$2"*/   # The trailing `/` restricts matches to directories.
}

그 다음에:

complete -C _pmd -o filenames pmd

-C실행 _pmd하면 작업 디렉토리를 복원할 필요가 없습니다(해결책의 질문).이 답변- 해당 명령이 궁극적으로 디렉터리를 변경하므로 해당 사용자에게는 영향을 미치지 않습니다. 재설정에 대해서도 걱정할 필요가 없습니다 nullglob. 사용-o filenames또한 디렉토리 항목에 특수 문자가 포함된 경우 readline이 적절하게 완성을 인용하도록 허용합니다. 서브셸을 사용하면 여기에 있는 다른 모든 것이 셸에 내장되므로 외부 명령을 분기하고 실행하는 비용이 절약됩니다.

답변2

더 간단하다는 것을 깨달았습니다... 마지막으로 완성 기능을 추가 ~/.bashrc하고 이를 명령 이름에 바인딩했습니다.

$ tail .bashrc

_pmd()
{   local cur opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    opts=$( cd /home/boffi/Music/ ; find * -type d | sed 's.$./.' )
    COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
}
complete -F _pmd pmd

$ pmd <TAB>
Aldous_Harding/
Aldous_Harding/Aldous_Harding/
Aldous_Harding/Designer/
Aldous_Harding/Party/
Aldous_Harding/Warm_Chris/
Madness/
Madness/The_Very_Best/
Mitski/
Mitski/Be_the_Cowboy/
Mitski/Bury_Me_At_Makeout_Creek/
Mitski/Laurel_Hell/
Mitski/Lush/
Mitski/Puberty_2/
Mitski/Retired_from_Sad,_New_Career_in_Business/
Mitski/The_Land_Is_Inhospitable_and_So_Are_We/
$ pmd 

관련 정보