saber ruta para obtener nombre formato etc ejemplo cuál comando archivo bash shell path

bash - ruta - obtener nombre de archivo shell



Detecta si la ruta del usuario tiene un directorio específico en ella (7)

Con /bin/bash , ¿cómo detectaría si un usuario tiene un directorio específico en su variable $ PATH?

Por ejemplo

if [ -p "$HOME/bin" ]; then echo "Your path is missing ~/bin, you might want to add it." else echo "Your path is correctly set" fi


Algo realmente simple e ingenuo

echo "$PATH"|grep -q whatever && echo "found it"

Donde sea lo que sea que estés buscando. En lugar de && puedes poner $? en una variable o use una declaración if adecuada.

Las limitaciones incluyen:

  • Lo anterior coincidirá con subcadenas de rutas más grandes (intente con la coincidencia en "bin" y probablemente la encuentre, a pesar de que "bin" no está en su ruta, / bin y / usr / bin son)
  • Lo anterior no expandirá automáticamente accesos directos como ~

O usando un perl de una sola línea:

perl -e ''exit(!(grep(m{^/usr/bin$},split(":", $ENV{PATH}))) > 0)'' && echo "found it"

Eso todavía tiene la limitación de que no hará expansiones de shell, pero no falla si una subcadena coincide. (Lo anterior coincide con " /usr/bin ", en caso de que no fuera claro).


Escribí la siguiente función de shell para informar si un directorio figura en la PATH actual. Esta función es compatible con POSIX y se ejecutará en shells compatibles como Dash y Bash (sin depender de las funciones específicas de Bash).

Incluye funcionalidad para convertir una ruta relativa a una ruta absoluta. Utiliza las utilidades readlink o realpath para esto, pero estas herramientas no son necesarias si el directorio proporcionado no tiene .. u otros enlaces como componentes de su ruta. Aparte de esto, la función no requiere ningún programa externo al shell.

# Check that the specified directory exists – and is in the PATH. is_dir_in_path() { if [ -z "${1:-}" ]; then printf "The path to a directory must be provided as an argument./n" >&2 return 1 fi # Check that the specified path is a directory that exists. if ! [ -d "$1" ]; then printf "Error: ‘%s’ is not a directory./n" "$1" >&2 return 1 fi # Use absolute path for the directory if a relative path was specified. if command -v readlink >/dev/null ; then dir="$(readlink -f "$1")" elif command -v realpath >/dev/null ; then dir="$(realpath "$1")" else case "$1" in /*) # The path of the provided directory is already absolute. dir="$1" ;; *) # Prepend the path of the current directory. dir="$PWD/$1" ;; esac printf "Warning: neither ‘readlink’ nor ‘realpath’ are available./n" printf "Ensure that the specified directory does not contain ‘..’ in its path./n" fi # Check that dir is in the user’s PATH. case ":$PATH:" in *:"$dir":*) printf "‘%s’ is in the PATH./n" "$dir" return 0 ;; *) printf "‘%s’ is not in the PATH./n" "$dir" return 1 ;; esac }

La parte que utiliza :$PATH: garantiza que el patrón también coincida si la ruta deseada es la primera o la última entrada en la PATH . Este ingenioso truco se basa en esta respuesta de Glenn Jackman en Unix y Linux .


Este es un enfoque de fuerza bruta, pero funciona en todos los casos, excepto cuando una entrada de ruta contiene dos puntos. Y no se utilizan programas que no sean el shell.

previous_IFS=$IFS dir_in_path=''no'' export IFS=":" for p in $PATH do [ "$p" = "/path/to/check" ] && dir_in_path=''yes'' done [ "$dir_in_path" = "no" ] && export PATH="$PATH:/path/to/check" export IFS=$previous_IFS


He aquí cómo hacerlo sin grep :

if [[ $PATH == ?(*:)$HOME/bin?(:*) ]]

La clave aquí es hacer que los dos puntos y los comodines sean opcionales usando el constructo ?() . No debería haber ningún problema con metacaracteres en este formulario, pero si desea incluir citas aquí es donde van:

if [[ "$PATH" == ?(*:)"$HOME/bin"?(:*) ]]

Esta es otra forma de hacerlo utilizando el operador de coincidencia ( =~ ) para que la sintaxis sea más parecida a la de grep :

if [[ "$PATH" =~ (^|:)"${HOME}/bin"(:|$) ]]


No hay absolutamente ninguna necesidad de utilizar utilidades externas como grep para esto. Esto es lo que he estado usando, que debería ser portable hasta versiones heredadas del shell Bourne.

case :$PATH: # notice colons around the value in *:$HOME/bin:*) ;; # do nothing, it''s there *) echo "$HOME/bin not in $PATH" >&2;; esac


Usar grep es excesivo, y puede causar problemas si está buscando algo que incluya incluir metacaracteres RE. Este problema se puede resolver perfectamente con el comando incorporado de bash:

if [[ ":$PATH:" == *":$HOME/bin:"* ]]; then echo "Your path is correctly set" else echo "Your path is missing ~/bin, you might want to add it." fi

Tenga en cuenta que agregar dos puntos antes de la expansión de $ PATH y la ruta de búsqueda resuelve el problema de coincidencia de subcadena; la doble cita de la ruta evita problemas con metacaracteres.


$PATH es una lista de cadenas separadas por : que describen una lista de directorios. Un directorio es una lista de cadenas separadas por / . Dos cadenas diferentes pueden apuntar al mismo directorio (como $HOME y ~ , o /usr/local/bin y /usr/local/bin/ ). Entonces, debemos arreglar las reglas de lo que queremos comparar / verificar. Sugiero que compare / verifique las cadenas enteras, y no los directorios físicos, sino que elimine los duplicados y los rastreos / .

Primero elimine el duplicado y el final / de $PATH :

echo $PATH | tr -s / | sed ''s///:/:/g;s/://n/g''

Ahora supongamos que $d contiene el directorio que desea verificar. Luego canalice el comando anterior para verificar $d en $PATH .

echo $PATH | tr -s / | sed ''s///:/:/g;s/://n/g'' | grep -q "^$d$" || echo "missing $d"