代码之家  ›  专栏  ›  技术社区  ›  epochwolf

检测用户路径中是否有特定目录

  •  38
  • epochwolf  · 技术社区  · 16 年前

    具有 /bin/bash ,如何检测用户的$PATH变量中是否有特定目录?

    例如

    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
    
    7 回复  |  直到 5 年前
        1
  •  150
  •   Gordon Davisson    8 年前

    使用 grep 是过度的,如果您正在搜索任何包含re元字符的内容,可能会导致麻烦。使用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
    

    请注意,在扩展$PATH和要搜索的路径之前添加冒号可以解决子字符串匹配问题;双重引用路径可以避免元字符的麻烦。

        2
  •  17
  •   Dennis Williamson    16 年前

    grep :

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

    这里的关键是使用 ?() 建筑此表单中的元字符应该不会有任何问题,但如果您想包含引号,则可以使用引号:

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

    这是使用match操作符执行此操作的另一种方法( =~ )所以语法更像 s:

    if [[ "$PATH" =~ (^|:)"${HOME}/bin"(:|$) ]]
    
        3
  •  12
  •   tripleee    8 年前

    绝对没有必要使用像这样的外部实用程序 grep 为了这个。下面是我一直在使用的,它应该可以移植回Bourne shell的旧版本。

    case :$PATH: # notice colons around the value
      in *:$HOME/bin:*) ;; # do nothing, it's there
         *) echo "$HOME/bin not in $PATH" >&2;;
    esac
    
        4
  •  5
  •   Adam Batkin    16 年前

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

    你要寻找的是什么。而不是 && $? 输入变量或使用适当的 if 陈述

    • 以上内容将匹配较大路径的子字符串(尝试匹配“bin”,它可能会找到它,尽管“bin”不在您的路径中,/bin和/usr/bin在其中)

    或者使用perl单行程序:

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

    /usr/bin “,以防不清楚)。

        5
  •  2
  •   Jekotia    6 年前

    if [[ $PATH =~ ^/usr/sbin:|:/usr/sbin:|:/usr/sbin$ ]] ; then
      do stuff
    fi
    

    这是怎么回事?=~操作符使用从3.0版开始的bash中提供的正则表达式模式支持。正在检查三种模式,由正则表达式或运算符分隔 | .

    在正则表达式中, ^ 匹配到行的开头,然后 $ 匹配到最后。如前所述,第一个模式只有在其查找的路径是$path中的第一个值时才会计算为true。第三个模式只有在其查找的路径是$path中的最后一个值时才会计算为true。当第二个模式在其他值之间找到它正在查找的路径时,它将计算为true,因为它正在查找$path变量使用的分隔符, : ,到正在搜索的路径的任一侧。

        6
  •  1
  •   Community Mohan Dere    9 年前

    我编写了以下shell函数来报告当前 PATH . 此函数与POSIX兼容,将在Dash和Bash等兼容shell中运行(不依赖于Bash特定的功能)。

    它包括将相对路径转换为绝对路径的功能。它使用 readlink realpath 实用程序,但如果提供的目录没有 .. 或其他链接作为其路径的组件。除此之外,该函数不需要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
    }
    

    使用的部件 :$PATH: 确保如果所需路径是中的第一个或最后一个条目,则模式也匹配 路径 . 这个聪明的把戏是基于 this answer by Glenn Jackman on Unix & Linux .

        7
  •  0
  •   jcr38    11 年前

    $PATH 是一个字符串列表,用 : / . 两个不同的字符串可能指向同一目录(如 $HOME ~ /usr/local/bin /usr/local/bin/ ).因此,我们必须修正我们想要比较/检查的规则。我建议比较/检查整个字符串,而不是物理目录,但要删除重复和尾随 / .

    / $PATH :

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

    现在假设 $d 包含要检查的目录。然后使用上一个命令进行检查 美元 在里面 $PATH .

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

    这是一种蛮力方法,但它适用于除路径条目包含冒号之外的所有情况。并且除了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
    
    推荐文章