shell - resueltos - scripts bash ejemplos
¿Cómo verificar si el comando existe en un script de shell? (7)
Cinco formas, 4 para bash y 1 adición para zsh:
-
type foobar &> /dev/null
-
hash foobar &> /dev/null
-
command -v foobar &> /dev/null
-
which foobar &> /dev/null
-
(( $+commands[foobar] ))
(zsh solamente)
Puede poner cualquiera de ellos en su cláusula if
. De acuerdo con mis pruebas ( https://www.topbug.net/blog/2016/10/11/speed-test-check-the-existence-of-a-command-in-bash-and-zsh/ ), el Los métodos primero y tercero se recomiendan en bash y el quinto se recomienda en zsh en términos de velocidad.
Estoy escribiendo mi primer script de shell. En mi script, me gustaría verificar si existe un cierto comando, y si no, instalar el ejecutable. ¿Cómo verificaría si este comando existe?
if #check that foobar command doesnt exist
then
#now install foobar
fi
En general, eso depende de tu caparazón, pero si usas bash, zsh, ksh o sh (según lo provisto por el guión), lo siguiente debería funcionar:
if ! type "$foobar_command_name" > /dev/null; then
# install foobar here
fi
Para una secuencia de comandos de instalación real, probablemente desee asegurarse de que el type
no vuelva correctamente en el caso en que exista un alias foobar
. En bash, podrías hacer algo como esto:
if ! foobar_loc="$(type -p "$foobar_command_name")" || [[ -z $foobar_loc ]]; then
# install foobar here
fi
Intenta usar el type
:
type foobar
Por ejemplo:
$ type ls
ls is aliased to `ls --color=auto''
$ type foobar
-bash: type: foobar: not found
Esto es preferible a lo which
por algunas razones:
1) las implementaciones predeterminadas solo admiten la opción -a
que muestra todas las opciones, por lo que debe buscar una versión alternativa para admitir alias
2) type te dirá exactamente lo que estás mirando (ya sea una función bash o un alias o un binario apropiado).
3) el tipo no requiere un subproceso
4) el tipo no puede ser enmascarado por un binario (por ejemplo, en un cuadro de Linux, si creas un programa llamado cuál aparece en el camino antes del real, which
, por ejemplo, las cosas tocan el type
ventilador), se construye un caparazón -en [sí, un subordinado inadvertidamente lo hizo una vez]
La pregunta no especifica un caparazón, por lo que para aquellos que usan fish (shell interactivo amigable):
if command --search foo >/dev/null do
echo exists
else
echo does not exist
end
Para una compatibilidad POSIX básica, use el indicador -v
que es un alias para --search
o -s
.
Una función que tengo en un script de instalación hecho exactamente para esto
function assertInstalled() {
for var in "$@"; do
if ! which $var &> /dev/null; then
echo "Install $var!"
exit 1
fi
done
}
Ejemplo de llamada:
assertInstalled zsh vim wget python pip git cmake fc-cache
Comprobar si un programa existe a partir de un script Bash lo cubre muy bien. En cualquier script de shell, es mejor que ejecute el command -v $command_name
para probar si $command_name
se puede ejecutar. En bash puedes usar hash $command_name
, que también hashes el resultado de cualquier búsqueda de ruta, o type -P $binary_name
si solo quieres ver binarios (no funciones, etc.)
which <cmd>
también vea las opciones which
admiten alias si corresponde a su caso.
Ejemplo
$ which foobar
which: no foobar in (/usr/local/bin:/usr/bin:/cygdrive/c/Program Files (x86)/PC Connectivity Solution:/cygdrive/c/Windows/system32/System32/WindowsPowerShell/v1.0:/cygdrive/d/Program Files (x86)/Graphviz 2.28/bin:/cygdrive/d/Program Files (x86)/GNU/GnuPG
$ if [ $? -eq 0 ]; then echo "foobar is found in PATH"; else echo "foobar is NOT found in PATH, of course it does not mean it is not installed."; fi
foobar is NOT found in PATH, of course it does not mean it is not installed.
$
PD: Tenga en cuenta que no todo lo que está instalado puede estar en PATH. Por lo general, para verificar si algo está "instalado" o no, uno utilizaría comandos relacionados con la instalación relevantes para el sistema operativo. Por ejemplo, rpm -qa | grep -i "foobar"
rpm -qa | grep -i "foobar"
para RHEL.