man ignorando alias

2

No Bash eu tenho um alias (para executar nvim quando eu digito vim ). Mas quando digito man vim , obtenho o homem para vim , não nvim . Meio que faz sentido, mas é claro que o que eu realmente quero é "o manual para o que eu recebo se eu rodar vim no shell ou de um script" não "o manual para um programa que eu não uso". Existe alguma maneira de configurar aliases ou man para trabalhar dessa maneira, ou é esperado que eu me lembre / pesquise aliases toda vez que executo man, para ter certeza de que estou procurando informações sobre a versão correta do aplicativo correto?

    
por Jeff Schaller 28.09.2017 / 11:37

4 respostas

5

Não, man não pode realmente pesquisar todos os seus aliases e atender à manpage do programa que você tem alias. O que você poderia fazer é configurar outro alias para a página do manual:

alias manvim="man nvim"  
    
por 28.09.2017 / 11:40
1

No bash, você pode usar type vim para pesquisar o que acontece quando você digita vim no prompt. Portanto, você pode substituir man por uma função de shell que verifica seu argumento e "faz a coisa certa".

932% type ls
ls is hashed (/bin/ls)
933% type vim
vim is aliased to 'nvim'

Como você pode ver, a saída de type exigiria um pouco de análise e lógica dependente de maiúsculas e minúsculas, mas certamente não é grande coisa para casos simples. A expansão de alias pode consistir em mais de uma palavra (por exemplo, alias lf a ls -AF ), mas isso também é fácil de ser manipulado.

Fica mais difícil se o alias é um pipeline (eu provavelmente mostraria a manpage para o primeiro comando e esperaria pelo melhor), e sem esperança se o seu comando é uma função shell em vez de um alias. Então, eu descompactaria os aliases e passaria todo o resto para man sem modificações. Aqui está uma prova de conceito (suporta apenas um argumento e nenhuma opção para man ):

function man {
    # Find out if the command is an alias, an executable, etc.
    local cmd

    p=$(type $1)
    case 'set $p; echo $3' in
       aliased) cmd=($(set 'command alias $1'; echo $2 | sed "s/.*='\([^ ]*\).*//"));;

       *) cmd=$1;;
    esac

    command man $cmd
}

Defina isso e man vim pesquisará seu alias e mostrará a página de manual de nvim , conforme solicitado.

    
por 28.09.2017 / 16:26
0

Se você shell, trata aliases desta maneira:

$ type vim
vim is aliased to 'nvim'
$ type -t vim
alias

tente isso. A função de shell a seguir irá verificar se seu argumento é um alias. Em caso afirmativo, extrairá a primeira palavra delimitada em branco do alias e executará man sobre isso.

man() {
  cmd="$1"
  if [ "$(type -t "$cmd")" == "alias" ]
  then cmd=$(type "$cmd" | sed -e 's/.*'//' -e "s/[ '].*//")
  fi
  command man $cmd
}

Uma solução mais abrangente incorporaria $IFS em vez de apenas em branco e permitiria aliases que contivessem ' e ' .

    
por 28.09.2017 / 16:26
0

Esta é uma má ideia. Pode-se usar uma função de shell que pode ou não encontrar o comando de alias. Eu quase sempre não substituo o nome padrão para as coisas, especialmente para não fazer o comando executar algum comando completamente diferente. Muitos ancinhos para pisar. Com este aviso em mente, no ZSH esta função pode ser algo como

# test aliases, for testing
# simple no args
alias emacs=ls
# with flags; need to pick first word and hope that's a command...
alias nano='ls -al'
# and oops there's also the ENV prefix form...
alias notepad='ASDF=blah ls -F'
# and also be sure to test with something-that-is-not-an-alias ...

# TODO call this 'man' to actually override the man
function crazyman {
  local -a cmd args

  # one may simply type 'man ... foo' or there could also be multiple
  # man pages to be viewed 'man ... foo bar' so must iterate over all
  # the hopefully-not-options-or-section-names arguments and try alias
  # lookups and all such... 'man ls -w' may also be legal depending on
  # the getops, by the way.
  while :; do
    if [[ -n $1 ]]; then
      while :; do
        # try to skip over 'man 1 foo' or 'man -w foo' forms to find what
        # is hopefully the foo command
        #
        # TODO 'n' section for TCL complicated as there could also be a
        # 'man n' command alongside "man n expr" or whatnot; this assumes
        # there is no 'man n' page that would ever be looked up. Other
        # non-numeric-prefixed man section names may also need to be
        # handled here, depending on the vendor...
        if [[ $1 =~ "^[0-9-]|^n$" ]]; then
          args+=($1)
          shift
        else
          break
        fi
      done

      cmd=(${(z)aliases[$1]})

      if (( #cmd )); then
        # aliases might be simple foo='bar ...' or more complicated
        # foo='ENV=asdf ... bar ...' where we need to dig to try to find
        # the bar command, and perhaps other complications as well :/
        # I did say this was a bad idea...
        while :; do
          if [[ $cmd[1] =~ "=" ]]; then
            shift cmd
          else
            break
          fi
        done
        args+=($cmd[1])
      else
        args+=($1)
      fi
      shift
    else
      break
    fi
  done

  command man $args
}

Com o command man $args substituído por print -l command man $args , algum teste manual (testes unitários apropriados seriam muito recomendáveis, dado o número de casos de borda no código acima):

% crazyman emacs
command
man
ls
% crazyman nano 
command
man
ls
% crazyman notepad
command
man
ls
% crazyman notepad nano
command
man
ls
ls
% crazyman nosuchalias
command
man
nosuchalias
% 

Portando este código para outros shells deixados como exercício para o leitor. Ou simplifique e não use este código, dada a complexidade para não muito de um ganho.

    
por 28.09.2017 / 17:38

Tags