`qual`, mas todos


19

Acho que a maioria está familiarizada com o whichcomando e o uso com frequência. Acabei de encontrar uma situação em que estou curioso, não apenas qual comando é o primeiro no meu caminho, mas quantos e onde estão todos os comandos em todos os meus caminhos. Tentei a página de manual (digitar man whichme fez rir), mas não vi nada.


1
No meu sistema, é a primeira coisa listados na página man: which --all.
Shawn J. Goff

2
No meu (linux) é apenas which -a.
desconhecido utilizador

Respostas:


23

Em alguns sistemas, which -amostra todas as correspondências. Se o seu shell for bash ou zsh¹, você poderá usar type: type foomostra a primeira correspondência e type -a foomostra todas as correspondências. Os três comandos type, whiche whencefazer principalmente a mesma coisa; eles diferem entre shells e sistemas operacionais em disponibilidade, opções e o que exatamente eles relatam. typeestá sempre disponível e mostra todos os nomes possíveis de comandos (aliases, palavras-chave, built-ins do shell, funções e comandos externos).

A única maneira totalmente portátil de exibir todas as correspondências é analisar a $PATHsi mesmo. Aqui está um script de shell que faz isso. Se você transformá-la em uma função shell, coloque o corpo da função entre parênteses (para que a mudança para IFSe set -fnão escape da função) e mude exitpara return.

#!/bin/sh
set -f       # disable globbing
IFS=:        # break words at : only
not_found=1
for d in $PATH; do
  if [ -f "$d/$x" ] && [ -x "$d/$x" ]; then
    printf '%s\n' "$d/$x"
    not_found=0
  fi
done
exit $not_found

¹ Ou ksh 93, de acordo com a documentação, embora o ksh 93s + 2008-01-31 só imprima a primeira correspondência quando eu tento.


Esse shcódigo não funciona corretamente se houver componentes vazios $PATH. Observe também que $IFSé um delimitador de campo (pelo menos em shells POSIX) enquanto em $PATH, dois pontos é usado como um separador de campos . Veja o whichscript encontrado no Debian para uma implementação correta.
Stéphane Chazelas

o typebuilt-in ksh93u+ 2012-08-01parece funcionar corretamente.
Stéphane Chazelas

5

O sinalizador --all ou -a mostrará todas as correspondências no seu caminho e aliases (pelo menos no Fedora, Ubuntu e CentOS):

which -a which

No AIX e Solaris, você chegará perto:

echo "$PATH" | sed -e 's/:/ /g' | \
while read -r p; do find "$p" -type f -name "which"; done

Você precisa de aspas duplas em torno das substituições de parâmetros, caso contrário, o script não funcionará se $PATHcontiver caracteres em branco ou shell globbing. read -ré necessário lidar com barras invertidas. Esse não é um bom método, pois findlevará muito tempo e poderá retornar correspondências falsas se um diretório $PATHcontiver subdiretórios. Felizmente, findnão é útil aqui; veja minha resposta.
Gilles 'SO- stop be evil'

Eu sabia que achava errado, pois certamente seria lento nos diretórios aninhados. Globbing e espaços em $ PATH? eww. Mas você está certo (embora você tenha sido gentil o suficiente para não dizer o mesmo): meu único diário foi mal escrito.
Eli Heady

1

Se você não tem um whichsuporte -aou está whencedisponível, faça o seu:

#!/bin/sh -f

IFS=":"
for PART in $PATH
do
  if test -x "$PART/$1"
  then
    echo $PART/$1
  fi
done

Está faltando set -fdesligar os olhos desprotegidos $PATH. test -fnão é suficiente, pois somente arquivos executáveis ​​são desejados aqui; você precisa test -x. Hmm, percebo que esqueci o teste de arquivo regular no meu script.
Gilles 'SO- stop being evil'

@ Gilles: editado de acordo com as suas dicas. Sou a favor da correção, mas acho whence README.txttão improvável quanto whence "file* wi?h we!rd name". Apenas tentando mostrar como é fácil atravessar $PATH.
Matt Bianco

0

O ksh e o zsh têm "donde" como um shell embutido. whence -afaz o que você quer no zsh:

 7:27AM 7 % whence -a cat
/usr/bin/cat
/bin/cat
/usr/bin/cat
/bin/cat

Eu tenho que limpar o PATH no zsh, tenho muitas duplicatas nele. whence -afunciona de maneira diferente no ksh:

$ whence -a cat
cat is a tracked alias for /usr/bin/cat

Devo dizer que também parece um comportamento potencialmente útil.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.