AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 476253
Accepted
somethingSomething
somethingSomething
Asked: 2018-10-19 01:34:30 +0800 CST2018-10-19 01:34:30 +0800 CST 2018-10-19 01:34:30 +0800 CST

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

  • 772

Eu tenho um functionno meu .bashrcarquivo. 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?

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

Por que não fazer assim:

up()
{
    limit=$1

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

Uso:

<<<>>>~$ up 3
<<<>>>/$
shell sed
  • 2 2 respostas
  • 2115 Views

2 respostas

  • Voted
  1. Best Answer
    Stephen Kitt
    2018-10-19T02:05:25+08:002018-10-19T02:05:25+08:00
    1. d=$d/..adiciona /..ao conteúdo atual da dvariável. dcomeça vazio, então a primeira iteração o torna /.., a segunda /../..etc.

    2. sed 's/^\///'descarta 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 destiver vazio neste ponto, você vá para o diretório pai. ( upsem 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 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 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(o athena-jotpacote no Debian):

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

    (baseado em uma variante sugerida por glenn jackman ).

    • 24
  2. user232326
    2018-10-19T14:13:02+08:002018-10-19T14:13:02+08:00

    Mas você pode explicar essas três coisas para mim?

    1. d=$d/..

      Isso concatena o conteúdo atual de var dcom /..e o atribui de volta a d.
      O resultado final é fazer duma string repetida como /../../../...

    2. sed 's/^///'

      Remova o início /da string fornecida d(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#/}.

    3. d=..

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


    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(as yash) não possui um localcomando. Uma solução mais portátil é:

      [ "$KSH_VERSION$YASH_VERSION" ] && typeset c='' d='' i='' || local c='' d='' i=''
      
    • A for((sintaxe não é portátil. 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 (vou usar cpara count):

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

      E, em seguida, limite o valor de contagem apenas a valores positivos:

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

    Esta função aceitará felizmente 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 tiver testado a função.

    • 2

relate perguntas

  • FreeBSD's sh: funções de lista

  • Existe uma maneira de fazer ls mostrar arquivos ocultos apenas para determinados diretórios?

  • o que grep -v grep faz

  • Como remover uma única linha entre duas linhas

  • Como salvar um caminho com ~ em uma variável?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve