【问题标题】:How to find a file on the $PATH in Bash?如何在 Bash 的 $PATH 上查找文件?
【发布时间】:2019-08-18 08:02:47
【问题描述】:

实用程序which 会在路径上找到一个程序,但是任意数据文件呢?

我一定是在寻找错误的东西,但我找不到任何使用标准实用程序的方法,所以我想写一个小 Bash 脚本来做。

$PATH 环境变量由冒号分隔,但尝试设置 IFS=':' 然后迭代结果对我不起作用。到目前为止,这是我所得到的:

IFS=':' DIRS=($PATH)
for d in $DIRS; do echo $d; done

此时它只输出我路径中的第一个条目,而不是全部。

想法?如果已经有执行此操作的标准命令,则没有理由编写脚本...

【问题讨论】:

  • 任意数据文件可能不应该在PATH的目录列表中。

标签: bash path posix


【解决方案1】:

使用这个,使用 bash 参数扩展find:

find ${PATH//:/\/ } -name 'file'

【讨论】:

  • 假设 PATH 中有一个目录,其中有一个空格。或 PATH 中目录中的文件,文件名中有空格。
  • 您也没有扩展 last PATH 条目中的文件。
  • 如果我可以使用find 来搜索$PATH 但用空格替换冒号是行不通的,那么这个解决方案会很棒
  • @GillesQuenot 我赞成你的find 解决方案,因为我喜欢它但是$PATH 中的目录中有空格时它就不起作用了
  • 我从不使用空格,特别是对于 PATH 目录,我也喜欢我的解决方案 ^^
【解决方案2】:

这里发生了一些事情:

  1. IFS=':' DIRS=($PATH)

    bash 将扩展变量before 设置IFS 和DIRS,所以到那时为时已晚。 你需要一些疯狂的东西,比如

    dirs=()
    while IFS= read -r -d: dir || [ "$dir" ]; do dirs+=("$dir"); done <<<"$PATH"
    

——不,那是错误的。首先扩展 $PATH 变量,然后设置 IFS,然后使用 IFS 拆分 DIRS 元素,因为它没有被引用。

  1. for d in $DIRS; do echo $d; done

    要遍历数组的所有元素,您需要

    for d in "${dirs[@]}" ...
    

    对于数组,$DIRS 等于 ${DIRS[0]},即第一个条目。

  2. 不要使用全大写变量名。覆盖关键系统变量太容易了。

  3. Quote your variables 除非你知道确切如果你不知道会发生什么。

【讨论】:

    【解决方案3】:

    使用 bash 循环在 PATH 上查找名为 $name 的文件:

    oldIFS=$IFS
    IFS=:
    for d in $PATH
    do
        [ -f "$d/$name" ] && echo "Found $d/$name"
    done
    IFS=$oldIFS
    

    在许多系统上,例如 debian,which 只是一个 shell 脚本,它使用非常相似的循环。看看less /usr/bin/which

    【讨论】:

      【解决方案4】:

      错误不在于赋值,而在于未循环数组。

      IFS=: dirs=($PATH)
      for dir in "${dirs[@]}"; do
          echo "$dir"
      done
      

      为我工作;或者更简洁

      printf '%s\n' "${dirs[@]}"
      

      如您所见,$dirs 仅返回数组中的第一项。

      要真正遍历这些目录以查找特定文件,也许可以尝试

      desired_file_name=$1  # or whatever
      for dir in "${dirs[@]}"; do
          test -e "$dir/$desired_file_name" || continue
          echo "$0: found $dir/$desired_file_name" >&2
      done
      

      另一种方法是

      find "${dirs[@]}" -name "$desired_file_name"
      

      (你的私有变量应该小写,所以我把DIRS改为dirs。少喊对眼睛也有好处。)

      【讨论】:

      • 呃,我想我没有测试我写的东西。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-19
      • 1970-01-01
      • 1970-01-01
      • 2014-03-02
      • 2022-11-27
      相关资源
      最近更新 更多