Eu tenho um function
no meu .bashrc
arquivo. Eu sei o que ele faz, aumenta X muitos diretórios comcd
Aqui está:
up()
{
local d=""
limit=$1
for ((i=1 ; i <= limit ; i++))
do
d=$d/..
done
d=$(echo $d | sed 's/^\///')
if [ -z "$d" ]; then
d=..
fi
cd $d
}
Mas você pode explicar essas três coisas para mim?
d=$d/..
sed 's/^\///'
d=..
Por que não fazer assim:
up()
{
limit=$1
for ((i=1 ; i <= limit ; i++))
do
cd ..
done
}
Uso:
<<<>>>~$ up 3
<<<>>>/$
d=$d/..
adiciona/..
ao conteúdo atual dad
variável.d
começa vazio, então a primeira iteração o torna/..
, a segunda/../..
etc.sed 's/^\///'
descarta o primeiro/
, então/../..
se torna../..
(isso pode ser feito usando uma expansão de parâmetro,d=${d#/}
).d=..
só faz sentido no contexto de sua condição:Isso garante que, se
d
estiver vazio neste ponto, você vá para o diretório pai. (up
sem argumento é equivalente acd ..
.)Essa abordagem é melhor do que iterativa
cd ..
porque preservacd -
— a capacidade de retornar ao diretório anterior (da perspectiva do usuário) em uma etapa.A função pode ser simplificada:
Isso pressupõe que queremos subir pelo menos um nível e adiciona n - 1 níveis, para que não seja necessário remover o início
/
ou verificar se há um arquivo$d
.Usando o Athena
jot
(oathena-jot
pacote no Debian):(baseado em uma variante sugerida por glenn jackman ).
d=$d/..
Isso concatena o conteúdo atual de var
d
com/..
e o atribui de volta ad
.O resultado final é fazer
d
uma string repetida como/../../../..
.sed 's/^///'
Remova o início
/
da string fornecidad
(echo $d) no código que você postou.Provavelmente melhor escrito
sed 's|^/||'
para evitar a barra invertida.Uma alternativa (mais rápida e simples) é escrever
d=${d#/}
.d=..
Atribua a string
..
ao vard
.Isso só faz sentido como forma de garantir que
d
tenha pelo menos um..
caso o testeif [ -z "$d" ]; then
sinalize que o vard
está vazio. E isso só pode acontecer porque o comando sed está removendo um caractere dod
.Se não houver necessidade de remover o caractere de d, não há necessidade de
sed
ouif
.O código em sua pergunta sempre subirá pelo menos um diretório.
Melhor
local d
é suficiente para garantir que a variável esteja vazia, nada mais é necessário.No entanto, local funciona apenas em alguns shells, como bash ou dash. Em específico,
ksh
(asyash
) não possui umlocal
comando. Uma solução mais portátil é:A
for((
sintaxe não é portátil. Melhor usar algo como:Robusto.
Se os valores fornecidos ao primeiro argumento da função puderem ser negativos ou texto, a função deve ser robusta para processar esses valores.
Primeiro, vamos limitar os valores a apenas números (vou usar
c
paracount
):E, em seguida, limite o valor de contagem apenas a valores positivos:
Esta função aceitará felizmente 0 ou qualquer texto (sem erros):
Remova o
echo \
quando tiver testado a função.