`cual`, pero todo


19

Creo que la mayoría está familiarizada con el whichcomando, y lo uso con frecuencia. Acabo de encontrarme con una situación en la que tengo curiosidad, no solo sobre qué comando está primero en mi camino, sino cuántos y dónde están todos los comandos en todos mis caminos. Probé la página de manual (escribir man whichme hizo reír), pero no vi nada.


1
En mi sistema, que es el primero que aparece en la página del manual: which --all.
Shawn J. Goff

2
En el mío (Linux) es solo which -a.
usuario desconocido el

Respuestas:


23

En algunos sistemas, which -amuestra todas las coincidencias. Si su shell es bash o zsh¹, puede usar typeen su lugar: type foomuestra la primera coincidencia y type -a foomuestra todas las coincidencias. Los tres comandos type, whichy whencehacen sobre todo lo mismo; difieren entre shells y sistemas operativos en disponibilidad, opciones y qué informan exactamente. typesiempre está disponible y muestra todos los posibles nombres similares a comandos (alias, palabras clave, funciones integradas de shell, funciones y comandos externos).

La única forma totalmente portátil de mostrar todas las coincidencias es analizarse $PATHusted mismo. Aquí hay un script de shell que hace esto. Si usted lo hace una función de shell, asegúrese de encerrar el cuerpo de la función entre paréntesis (de modo que el cambio en IFSy set -fno escapan a la función), y el cambio 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, según la documentación, aunque ksh 93s + 2008-01-31 solo imprime la primera coincidencia cuando lo intento.


Ese shcódigo no funciona correctamente si hay componentes vacíos $PATH. También tenga en cuenta que $IFSes un delimitador de campo (al menos en shells POSIX) mientras que en $PATH, dos puntos se utiliza como separador de campo . Vea el whichscript que se encuentra en Debian para una implementación correcta.
Stéphane Chazelas

el typeincorporado en ksh93u+ 2012-08-01parece funcionar correctamente.
Stéphane Chazelas

5

El indicador --all o -a le mostrará todas las coincidencias en su camino y alias (al menos en Fedora, Ubuntu y CentOS):

which -a which

En AIX y Solaris, esto te acercará:

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

Necesita comillas dobles alrededor de las sustituciones de parámetros, de lo contrario, el script no funcionará si $PATHcontiene espacios en blanco o caracteres de concha. read -rEs necesario hacer frente a las barras invertidas. Este no es un buen método porque findllevará mucho tiempo y puede devolver coincidencias espurias si un directorio $PATHcontiene subdirectorios. Afortunadamente, findno es útil aquí; mira mi respuesta
Gilles 'SO- deja de ser malvado'

Sabía que find se sentía mal, ya que sin duda sería lento en los directorios anidados. Globbing y espacios en $ PATH? eww. Pero tienes razón (aunque fuiste lo suficientemente amable como para no decir tanto): mi único revestimiento estaba mal escrito.
Eli Heady

1

Si no tiene un whichsoporte -ao no está whencedisponible, enrolle el suyo:

#!/bin/sh -f

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

Te falta set -fdesactivar el engorde de los desprotegidos $PATH. test -fno es suficiente ya que solo se necesitan archivos ejecutables aquí; lo que necesita test -x. Hmm, me doy cuenta de que olvidé la prueba de archivo normal en mi script.
Gilles 'SO- deja de ser malvado'

@Gilles: editado según tus consejos. Estoy a favor de la corrección, pero me parece whence README.txttan improbable como whence "file* wi?h we!rd name". Solo trato de mostrar lo fácil que es atravesar $PATH.
MattBianco

0

ksh y zsh tienen "de dónde" como shell incorporado. whence -ahace lo que quieres bajo zsh:

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

Tengo que limpiar PATH en zsh, tengo muchos duplicados. whence -afunciona de manera diferente bajo ksh:

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

Tengo que decir que también parece un comportamiento potencialmente útil.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.