Eu tenho alguns diretórios com arquivos de música
$ 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
e um roteiro
$ 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}
$
Quando eu cd ~/Music
uso conclusões, meu comando funciona conforme o esperado; quando o executo a partir de um diretório genérico ele não funciona, pois a conclusão (na melhor das hipóteses) coloca os nomes completos dos caminhos na linha de comando.
Como posso convencer o bash/readline a concluir em diretórios/subdiretórios com raiz ~/Music
, sem colocar o nome completo do caminho na linha de comando?
Eu li o comando autocomplete de uma determinada pasta e Bash autocomplete: List files and directories from other directory .
No primeiro caso, o comando leva um único argumento, no segundo caso o nome completo do caminho é colocado na linha de comando e não pode ser concluído em subdiretórios.
Seguindo uma sugestão em um comentário, implementei o que é sugerido aqui , mas completar depois pmds
listaria todos os executáveis em meu sistema, e se eu executar o comando de qualquer maneira, sou teletransportado para~/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
$
Experimentando um pouco, existe uma maneira ainda mais simples de usar o
complete -C
. Defina uma função que grave os nomes dos diretórios para conclusão na saída:Então:
-C
executa o_pmd
em um subshell, portanto, não precisamos restaurar o diretório de trabalho (um problema com a solução nesta resposta - que não afetou o usuário, pois o comando deles alterou o diretório no final). Nem precisamos nos preocupar em redefinirnullglob
. O uso-o filenames
também permite que o readline cite a conclusão apropriadamente se você tiver entradas de diretório com caracteres especiais. Embora um subshell seja usado, todo o resto aqui é integrado ao shell, portanto, economizamos o custo de bifurcação e execução de um comando externo.Percebi que é mais simples... No final adicionei uma função de conclusão ao meu
~/.bashrc
e vinculei-a ao meu nome de comando