Eu tenho um comando chamado up
(como uma função no meu bashrc) que me permite ir facilmente para diretórios especificados acima daquele em que estou. O comando funciona bem, no entanto, adicionar a conclusão da guia bash o tornaria ainda mais útil. Eu escrevi um script de conclusão que identifica os diretórios no caminho atual e os lista para conclusão. O problema que estou tendo é que sempre que mudo o diretório, o script de conclusão parece não ser recarregado, me dando os mesmos resultados como se eu ainda estivesse no diretório anterior. Consegui corrigir isso para o up
comando adicionando exec bash
à função de comando, no entanto, não tenho certeza se posso fazer isso para um comando de alteração de diretório arbitrário. Eu suspeito que isso poderia ser feito apenas adicionando exec bash
para sempre que ocd
comando é executado, mas não tenho certeza de qual seria a melhor maneira de fazer isso.
Como um exemplo:
Se eu abrir um terminal, estou no meu diretório pessoal:
~$
Se eu digitar up <TAB><TAB>
, recebo:
~$ up
username home
onde nome de usuário é meu nome de usuário no meu pc. Eu então cd em dir1/dir2/
, e digito up <TAB><TAB>
, e obtenho:
~/dir1/dir2$ up
username home
novamente, mesmo que eu tenha mudado meu diretório.
O código para meu script de conclusão e script up são os seguintes:
Roteiro de conclusão:
#/usr/bin/env bash
LS=$(echo $PWD)
LSARRAY=${LS//\// }
complete -W "$LSARRAY" up
Comando para cima (em .bashrc)
LS=$(echo $PWD)
LSARRAY=(${LS//\// })
i=1
if [[ $LS == *$1/* ]]; then
FIND=$1
if [[ $1 == */* ]]; then
ARR=(${FIND//\// })
FIND=${ARR[${#ARR[@]}-1]}
fi
while [ "${LSARRAY[${#LSARRAY[@]}-$i]}" != "$FIND" ] && [ $i != ${#LSARRAY[@]} ]; do
cd ../
i=$(($i+1))
done
exec bash
else
echo "Did not find directory $1"
fi
Aqui está uma implementação alternativa de sua
up
função (incluindo sua contraparte de conclusão programável) que tenta:IFS
variável, o que não é trivial para restaurar adequadamente ;.
,..
; manipulado de forma arbitrária aqui, você pode querer adaptar o código com base em sua preferência);A
up
função:E sua
_up
função de conclusão e especificação (ocomplete
comando):Ambos os trechos de código devem ser colocados em seu arquivo
.bashrc
. Se você estiver usando o bash-completion, você pode preferir armazenar as funções e especificações de conclusão em$XDG_DATA_HOME/bash-completion
ou~/.local/share/bash-completion
ou~/.bash_completion
(consulte o FAQ na página com tinta para obter mais informações sobre isso).Argumentos contendo barras são descartados propositalmente porque, caso contrário (a meu ver), além disso
foo/bar
, devemos cuidar, por exemplo,foo///bar/./../baz
(ou seja, realizar alguma forma de canonização).O uso de arrays associativos (
declare -A
) requer Bash >= 4.0.Seu problema é que a avaliação das variáveis
LS
eLSARRAY
acontece apenas uma vez, então ele sempre completará oup
comando com as pastas pai daPWD
que você tinha quando definiu a conclusão.Para extrair as pastas pai dinamicamente, você precisará criar uma função para a conclusão. Dessa forma, as variáveis
LS
eLSARRAY
serão avaliadas toda vez que você tentar completar sua base de comando up em sua atual atualPWD
.Você consegue fazer isso:
O principal problema foi (como mencionado na resposta anterior) que suas possibilidades de conclusão não foram geradas dinamicamente.
Além disso, seu código não funciona com espaços em branco no nome do diretório. O meu não funciona com novas linhas no nome do diretório.
Eu também removi o diretório atual da lista de seleção porque isso não faz sentido.
Eu não entendo o que você
if [[ $1 == */* ]]
deve fazer (deve serif [[ $FIND == */* ]]
de qualquer maneira), pois os nomes de diretório nunca podem conter/
, então eu o removi.