Você pode explicar essas três coisas neste código bash para mim, por favor?

10

Eu tenho um function no meu arquivo .bashrc e não consigo envolvê-lo nisso. Eu sei o que ele faz, ele vai X muitos diretórios com cd

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?

  1. d=$d/..
  2. sed 's/^\///'
  3. d=..

Por que não apenas fazer assim:

up()
{
    limit=$1

    for ((i=1 ; i <= limit ; i++))
    do
        cd ..
    done
}

Uso:

<<<>>>~$ up 3
<<<>>>/$
    
por somethingSomething 18.10.2018 / 11:34

2 respostas

24
  1. d=$d/.. adiciona /.. ao conteúdo atual da variável d . d começa vazio, depois a primeira iteração torna /.. , o segundo /../.. etc.

  2. sed 's/^\///' cai o primeiro / , então /../.. se torna ../.. (isso pode ser feito usando uma expansão de parâmetro, d=${d#/} ).

  3. d=.. só faz sentido no contexto de sua condição:

    if [ -z "$d" ]; then
      d=..
    fi
    

    Isso garante que, se d estiver vazio nesse ponto, você vá para o diretório pai. ( up sem argumento é equivalente a cd .. .)

Essa abordagem é melhor do que iterativa cd .. porque preserva cd - - a capacidade de retornar ao diretório anterior (da perspectiva do usuário) em uma única etapa.

A função pode ser simplificada:

up() {
  local d=..
  for ((i = 1; i < ${1:-1}; i++)); do d=$d/..; done
  cd $d
}

Isso pressupõe que queremos subir pelo menos um nível e adicionar níveis n - 1 , portanto, não é necessário remover o% principal/ ou verificar se há $d vazia .

Usando o Athena jot (o pacote athena-jot no Debian):

up() { cd $(jot -b .. -s / "${1:-1}"); }

(baseado em um variante sugerido por glenn jackman ).

    
por 18.10.2018 / 12:05
2

But can you explain these three things from it for me?

  1. d = $ d /..

    Isso concatena o conteúdo atual de var d com /.. e o atribui de volta a d .
    O resultado final é tornar d uma string repetida como /../../../.. .

  2. sed 's / ^ ///'

    Remova o / inicial da string fornecida, d (echo $ d) no código que você publicou.
    Provavelmente melhor escrito como sed 's|^/||' para evitar a barra invertida.

    Uma alternativa (mais rápida e simples) é escrever d=${d#/} .

  3. d = ..

    Atribua a string .. ao var d .
    Isso só faz sentido como uma forma de garantir que d tenha pelo menos um .. caso o teste if [ -z "$d" ]; then indique que o var d está vazio. E isso só pode acontecer porque o comando sed está removendo um caractere de d .
    Se não houver necessidade de remover o caractere de d, não haverá necessidade de sed ou if .

O código da sua pergunta sempre vai subir pelo menos um diretório.

Melhor

  • local d é suficiente para garantir que a variável esteja vazia, nada mais é necessário.
    No entanto, o local funciona apenas em alguns shells como bash ou dash. Em específico, ksh (como yash ) não possui um comando local . Uma solução mais portátil é:

    [ "$KSH_VERSION$YASH_VERSION" ] && typeset c='' d='' i='' || local c='' d='' i=''
    
  • A sintaxe for(( não é portável. Melhor usar algo como:

    while [ "$((i+=1))" -lt "$limit" ]; do
    
  • 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 (usarei c para count ):

    c=${1%%[!0-9]*}
    

    E limite o valor da contagem apenas para valores positivos:

    let "c = (c>0)?c:0"
    

Esta função aceita hapily 0 ou qualquer texto (sem erros):

up()
{
    [ "$KSH_VERSION$YASH_VERSION" ] && typeset c='' d='' i='' || local c='' d='' i=''
    c=${1%%[!0-9]*}
    c=$(((c>0)?c:0))
    while [ "$((i+=1))" -le "$c" ]; do d="$d../"; done
    echo \
        cd "${d%/}"         # Removing the trailing / is not really needed for cd
                            # but it is nice to know it could be done cleanly.
}

up 2
up 0
up asdf

Remova o echo \ quando você testou a função.

    
por 19.10.2018 / 00:13