2009-09-08 15 views

Respuesta

3

Algo muy simple e ingenuo:

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

Donde todo lo que sea lo que usted está buscando. En lugar de && puede poner $? en una variable o usar una declaración if adecuada.

limitaciones incluyen:

  • Lo anterior coincidirá con subcadenas de caminos más grandes (utilizar la concordancia en "bin" y es probable que lo encontrará, a pesar del hecho de que "bin" no se encuentra en su camino,/bin y/usr/bin son)
  • Lo anterior no se expandirá automáticamente accesos directos como ~

o utilizando 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).

+1

Relacionado con el principio/final de la línea y dos puntos como en la respuesta de JasonWoof se ocupa de la limitación de coincidencia de su subcadena. La expansión de Tilde no es un problema común, ya que la mayoría de las personas permiten que se expanda cuando se asigna (por ejemplo, '' PATH = "~/bin: $ PATH' '), pero se puede solucionar con una sustitución si es necesario. – Cascabel

+2

Bien, alguien votó negativamente esto después de 3.5 años. Y no dejó un comentario. Cojo. –

+0

Estoy usando la solución grep que envuelve el patrón con dos puntos. – elias

102

El uso de grep es exagerado, y puede causar problemas si está buscando algo que incluya incluir metacaracteres de RE. Este problema se puede resolver perfectamente bien con orden interna [[ comando 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 la adición de dos puntos antes de que tanto la expansión de $ PATH y el camino para buscar resuelve el problema de subcadenas coincidentes; la doble cita de la ruta evita problemas con metacaracteres.

+4

Si '$ HOME/bin' está al principio o al final de' $ PATH', entonces no es probable que haya dos puntos en cada extremo. –

+8

No estoy seguro de entender tu objeción. Por ejemplo, si $ PATH es/usr/bin:/bin:/usr/sbin:/sbin:/home/fred/bin, entonces ":/usr/bin:/bin:/usr/sbin:/sbin:/home/fred/bin: "coincidirá *":/home/fred/bin: "* bien. –

+6

Tienes razón. No pude ver el papel de los dos puntos alrededor de "$ PATH". Lo siento. –

10

Aquí es cómo hacerlo sin grep:

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

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

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

Ésta es otra manera de hacerlo utilizando el operador de partido (=~) lo que la sintaxis es más como grep 's:

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

El '? (: *)' Es un patrón [extendido global] (https://mywiki.wooledge.org/glob#extglob) que debe habilitarse explícitamente por separado en la mayoría de las plataformas ('shopt -s extglob'). – tripleee

0

$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/compruebe las cadenas enteras, y no los directorios físicos, pero elimine el duplicado y el final /.

primer duplicado quitar y finales / de $PATH:

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

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

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

me escribió la siguiente función de shell reportar si un directorio aparece en la corriente PATH. 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 la 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 suministrado 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 usando :$PATH: asegura que el patrón también coincide si la ruta deseada es la primera o la última entrada en el PATH. Este astuto truco se basa en this answer by Glenn Jackman on Unix & Linux.

0

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 
Cuestiones relacionadas