"quale", ma tutto


19

Penso che la maggior parte abbia familiarità con il whichcomando e lo uso spesso. Mi sono appena imbattuto in una situazione in cui sono curioso non solo quale comando sia il primo nel mio percorso, ma quanti e dove sono tutti i comandi in tutti i miei percorsi. Ho provato la pagina man (digitando man whichmi ha fatto ridere), ma non ho visto nulla.


1
Sul mio sistema, è la prima cosa elencato nella pagina man: which --all.
Shawn J. Goff,

2
Sul mio (linux) è solo which -a.
utente sconosciuto

Risposte:


23

Su alcuni sistemi, which -amostra tutte le partite. Se la tua shell è bash o zsh¹, puoi typeinvece usare : type foomostra la prima partita e type -a foomostra tutte le partite. I tre comandi type, whiche whencefanno principalmente la stessa cosa; differiscono tra shell e sistemi operativi per disponibilità, opzioni e cosa riportano esattamente. typeè sempre disponibile e mostra tutti i possibili nomi simili a comandi (alias, parole chiave, incorporati della shell, funzioni e comandi esterni).

L'unico modo completamente portatile per visualizzare tutte le partite è analizzare $PATHte stesso. Ecco uno script di shell che fa questo. Se lo rendi una funzione shell, assicurati di racchiudere il corpo della funzione tra parentesi (in modo che il passaggio a IFSe set -fnon sfugga alla funzione) e cambi exita 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

¹ O ksh 93, secondo la documentazione, sebbene ksh 93s + 2008-01-31 stampi la prima partita solo quando provo.


Quel shcodice non funziona correttamente se ci sono componenti vuoti in $PATH. Si noti inoltre che $IFSè un delimitatore di campo (almeno nelle shell POSIX) mentre in $PATH, i due punti vengono utilizzati come separatori di campo . Vedi lo whichscript trovato su Debian per una corretta implementazione.
Stéphane Chazelas,

il typebuilt-in ksh93u+ 2012-08-01sembra funzionare correttamente.
Stéphane Chazelas,

5

Il flag --all o -a mostrerà tutte le partite nel tuo percorso e alias (almeno su Fedora, Ubuntu e CentOS):

which -a which

Su AIX e Solaris, questo ti avvicinerà:

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

Sono necessarie doppie virgolette per la sostituzione dei parametri, altrimenti lo script non funzionerà se $PATHcontiene spazi vuoti o caratteri globbing della shell. read -rè necessario per far fronte alle barre rovesciate. Questo non è un buon metodo perché findimpiegherà molto tempo e potrebbe restituire corrispondenze spurie se una directory in $PATHcontiene sottodirectory. Fortunatamente, findnon è utile qui; vedi la mia risposta.
Gilles 'SO-smetti di essere malvagio' il

Sapevo che trovavo sbagliato perché sarebbe certamente lento nelle directory nidificate. Globbing e spazi in $ PATH? eww. Ma hai ragione (anche se sei stato abbastanza gentile da non dire così tanto): il mio unico liner era scritto male.
Eli Heady,

1

Se non disponi di un whichsupporto -a, o whencedisponibile, tira il tuo:

#!/bin/sh -f

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

Ti stai perdendo set -fper disattivare i globbing sui non protetti $PATH. test -fnon è sufficiente poiché qui sono desiderati solo file eseguibili; hai bisogno test -x. Hmm, mi rendo conto di aver dimenticato il normale test dei file nella mia sceneggiatura.
Gilles 'SO- smetti di essere malvagio' il

@Gilles: modificato in base ai tuoi suggerimenti. Sono tutto per correttezza, ma trovo whence README.txtimprobabile come whence "file* wi?h we!rd name". Sto solo cercando di mostrare quanto sia facile attraversare $PATH.
MattBianco,

0

ksh e zsh hanno "whence" come shell integrata. whence -afa quello che vuoi sotto zsh:

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

Devo ripulire il PERCORSO in zsh, ho molti duplicati. whence -afunziona diversamente con ksh:

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

Devo dire che anche questo sembra un comportamento potenzialmente utile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.