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 / 746047
Accepted
Anil
Anil
Asked: 2023-05-16 21:10:07 +0800 CST2023-05-16 21:10:07 +0800 CST 2023-05-16 21:10:07 +0800 CST

Como posso alias `...` para `../..` no Bash?

  • 772

Como posso alias ...para ../..no Bash?

Estou ciente de que outras respostas permitem, alias '...'='cd ../..'mas gostaria de poder abordar o diretório dois níveis acima com outros comandos, permitindo:

cd ...
ls ...
realpath ...

Eu tentei alias '...'='../..', mas ao tentar usar isso, recebo o seguinte:

$ alias '...'='../..'
$ type ...
... is aliased to '../..'
$ cd ...
bash: cd: ...: No such file or directory

Estou ciente de que os aliases devem ser usados ​​com comandos. Existe uma maneira de obter a mesma funcionalidade para um caminho neste caso?

bash
  • 4 4 respostas
  • 3665 Views

4 respostas

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2023-05-17T02:35:32+08:002023-05-17T02:35:32+08:00

    Se mudar para zsh for uma opção, você pode usar aliases globais para isso:

    alias -g ...=../..
    

    Mas, em qualquer caso, isso só é expandido quando ...é reconhecido como um token totalmente delimitado por conta própria. Será expandido em echo ...ou echo ...> fileou (echo ...)mas não em echo .../xou echo ~/...ou echo "...").

    Os aliases normais do estilo csh, seja em bash ou zsh, são expandidos apenas quando na posição de comando ou após outra expansão de alias terminando em um caractere em branco. No zsh, porém, se você definir a autocdopção, inserir ../..ou outro diretório quando o nome do comando for transformado em cd ../.., então

    $ set -o autocd
    $ alias ...=../.. ....=../../..
    $ ...
    

    Seria uma maneira de cdentrar ../.., mas também seria alias ...='cd ../..'ou ...() cd ../...

    Uma abordagem melhor que venho usando há muitos anos é vincular a .chave a algo que insere /..em vez de .se o que resta do cursor terminar em ..:

    magic-dot() {
      if [[ $LBUFFER = (|*[[:blank:]/]).. ]]; then
        repeat ${NUMERIC-1} LBUFFER+=/..
      else
        zle self-insert
      fi
    }
    zle -N magic-dot
    bindkey . magic-dot
    

    Em seguida, entrar ...é imediata e visualmente transformado em ../..e pressionar .novamente muda para ../../..e assim por diante. Se estiver no emacsmodo, ..seguido por Alt+ 4, .torna-o ../../../../.., por exemplo, ( /..anexado 4 vezes) usando o tratamento usual de prefixo NUMÉRICO .

    Costumava atrapalhar ao copiar/colar coisas que continham ..., mas isso não é mais um problema agora que o suporte para colagem entre colchetes foi introduzido. Para inserir um literal ..., você pode pressionar Ctrl+ vantes do terceiro .ou usar barras invertidas, aspas ou qualquer coisa que faça com que o que resta do cursor ( $LBUFFERacima) não termine <blanks-or-slash>..em .\.., ..\., whatever/'...'...

    Uma limitação intencional do acima é que, por exemplo, em sort -o..., o ...não é expandido. Use sort -o ...em vez disso. O mesmo vale para cd '.../***'-> cd ...'/***'. Você pode alterar o teste acima para [[ $LBUFFER = (|*[^.]).. ]]ser ...expandido ../..em mais contextos, embora isso aumente a probabilidade de ser expandido em lugares que você não gostaria.

    Podemos tornar o tratamento de argumentos numéricos um pouco mais útil, permitindo 4 níveis acima (expandir para ), por exemplo, com:cd Alt+4.cd../../../..

    magic-dot() {
      if (( NUMERIC )) && [[ $LBUFFER = (|*[[:blank:]/:]) ]]; then
        LBUFFER+=..
        (( NUMERIC-- ))
      fi
        
      if [[ $LBUFFER = (|*[[:blank:]/]).. ]]; then
        repeat ${NUMERIC-1} LBUFFER+=/..
      else
        zle self-insert
      fi
    }
    zle -N magic-dot
    bindkey . magic-dot
    

    Conforme mencionado por @Gilles no comentário, versões recentes do bash adicionaram suporte limitado para editar o buffer de linha em comandos vinculados a chaves, para que você pudesse fazer algo semelhante com:

    insert_before_cursor() {
      # for the equivalent of zsh's repeat $1 LBUFFER+=$2
      local i
      for (( i = 0; i < $1; i++ )); do
        READLINE_LINE=${READLINE_LINE:0:READLINE_POINT}$2${READLINE_LINE:READLINE_POINT}
        (( READLINE_POINT += ${#2} ))
      done
    }
    
    magic-dot() {
      (( ${READLINE_ARGUMENT-1} > 0 )) || return
      if [[ -v READLINE_ARGUMENT && ${READLINE_LINE:0:READLINE_POINT} = ?(*[[:blank:]/]) ]]; then
        insert_before_cursor 1 ..
        (( READLINE_ARGUMENT-- ))
      fi
    
      if [[ ${READLINE_LINE:0:READLINE_POINT} = ?(*[[:blank:]/]).. ]]; then
        insert_before_cursor "${READLINE_ARGUMENT-1}" /..
      else
        insert_before_cursor "${READLINE_ARGUMENT-1}" .
      fi
    }
    bind -x '".":magic-dot'
    
    # work around a bug in current versions of bash for the numeric
    # argument to work properly, that means however that you lose the
    # insert-last-argument normally bound to Meta-. (also on Meta-_)
    bind -x '"\e.":magic-dot'
    

    Você precisa do bash 4.0 ou superior para $READLINE_LINE(não $READLINE_LINE_BUFFERcomo incorreto em parte da documentação) e $READLINE_POINT, e 5.2 ou superior para $READLINE_ARGUMENT, embora, conforme observado acima, ainda não funcione corretamente.

    • 25
  2. terdon
    2023-05-16T21:45:46+08:002023-05-16T21:45:46+08:00

    Você não pode usar aliases para isso, aliases são sobre coisas que você executa, não coisas que você passa para um comando como argumentos. Você poderia usar uma variável, mas isso significaria digitar algo um pouco diferente. Mas se você usar um nome de variável curto, pode ser apenas dois caracteres:

    $ pwd
    /home/terdon/foo/bar
    $ v="../.."
    $ realpath "$v"
    /home/terdon
    

    Se isso funcionar para você, você pode adicionar a definição de variável aos seus arquivos ~/.profileou ~/.bash_profilee terá acesso a ela em suas sessões de shell:

    v="../.."
    
    • 10
  3. Soubhik Biswas
    2023-05-17T15:12:17+08:002023-05-17T15:12:17+08:00

    Existem várias maneiras de alcançar seu objetivo

    MÉTODO 1: Modifique o código-fonte do bash

    Este método é específico da versão, mas ainda é recomendado, pois é a melhor maneira de fazer as coisas. O que eu fiz foi modificado builtins/cd.defde forma que, antes de verificar o caminho absoluto, verifique se o primeiro argumento é, ...se for o caso, define o dirnamepara ../..(soa apenas como alias)

    PASSO 1: Baixar bash-5.1.16.tar

    wget http://ftp.gnu.org/gnu/bash/bash-5.1.16.tar.gz
    

    PASSO 2: Obtenha e aplique o patch bash_5.16_cd_three_dot.patch

    tar -xf bash-5.1.16.tar.gz
    cd bash-5.1.16
    wget https://gist.githubusercontent.com/s0ubhik/6685effe6e46f6a840bb480c5d657933/raw/5736ce64cbb0b009d872c21f40d69c8ee2942b74/bash_5.16_cd_three_dot.patch
    patch -p0 < bash_5.16_cd_three_dot.patch
    

    PASSO 3: Compile e execute

    ./configure
    make
    ./bash
    

    CD ... bash

    MÉTODO 2: Habilitar autocd no shopt

    Esses métodos não fazem exatamente o que você deseja, mas acho melhor usar técnicas inteligentes de alias

    shopt -s autocd
    

    Agora, se você quiser voltar um diretório, basta usar ..e para dois../.. CD automático

    MÉTODO 3: Use um alias inteligente

    Este método funciona, mas não é recomendado, pois pode ser problemático para vários scripts usados cd. você pode adicionar isso ao seu .bashrcou criar um arquivo separado e incluir o arquivo em.bashrc

    cd_mod(){
      if [ "$1" == "..." ]; then
        \cd ../../
      else
        \cd $@
      fi
    }
    
    alias cd=cd_mod
    

    cd_mod cd

    • 4
  4. rrauenza
    2023-05-17T13:31:33+08:002023-05-17T13:31:33+08:00

    Você não pode usar alias diretamente porque ...é um argumento para cd, mas eu vi algumas pessoas cd..serem alias cd .., então você poderia fazer o mesmo com todos os comandos:

    alias cd...='cd ../..'
    

    Por outro lado...

    $ cat ~/mycd 
    if [ "$1" = '...' ]
    then
      # Use \cd to prevent recursion
      \cd ../..
    else
      \cd "$1"
    fi
    

    E então

    alias cd=". ~/mycd"
    

    Alternativamente,

    mycd() { if [ "$1" = '...' ]; then \cd ../..; else \cd "$1"; fi; }
    alias cd="mycd"
    
    • 2

relate perguntas

  • exportar variáveis ​​​​env programaticamente, via stdout do comando [duplicado]

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

Sidebar

Stats

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

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

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

    • 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

    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
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • 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
    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

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