递归递归直到找到文件

Ascending recursion until file is found

首先,我对 shell 脚本编写还很陌生。但是我越来越喜欢它了。

我真的很喜欢在终端上工作,这就是为什么我开始考虑通过创建个人提示来定制它以满足我的需要。你知道,专业开发者 - 专业提示:-P

目前我对此非常满意。它具有您希望提示具有的所有基本信息。

但我很想在我的提示中添加一个非标准的 "feature",但我的新手让我很不爽。

我想做的是创建一个方法来查找特定文件 - 在我的例子中 composer.json - 在当前目录中。如果没有找到,它应该跳上一层并在那里寻找它。如果在那里没有找到,它应该一次又一次地跳到另一层,直到找到文件。

在某些时候,您可能会遇到根 / 然后它应该会中止。

问题是,我希望能够从 composer.lock 文件中的一些专门安装的软件包中提取版本号,并在我的提示中显示。

我在当前目录中查找文件似乎没有问题,但问题是递归升序部分。

我目前正在使用 ZSH shell。不确定除了 Bash.

之外是否提供了一些其他功能来实现此目的

希望你们中的一些出色的开发者可以帮助 shell 粉丝。

如果我说得不够清楚,或者如果您需要的某些信息我没有提供,请不要犹豫,尽管提出来,我会尽一切努力提供。

我有点困惑...你说你在搜索 composer.json 但在谈论 composer.lock ???所以下面我给大家一个找composer.lock的脚本,如果你想改哪个文件你可以改脚本开头的file-变量'正在寻找!

我假设你的命令 composer show -i | grep "laravel/framework" 可以在文件 composer.lock 所在的任何目录中工作,正如你在评论中所说的那样。 因此,如果必须在不更改当前目录的情况下完成,则有 2 个选项:

  1. 最干净的方法:使用 pushd 将当前目录推入堆栈,然后在退出之前使用 popd 弹出目录。基于 this website 我们不应该在没有参数的情况下调用 pushd

    One difference is the way pushd is handled if no arguments are given. As in csh, this exchanges the top two elements of the directory stack

    然后你可以试试这个:

    file=composer.lock
    unset failure
    # pushd actually current directory and change to current directory
    pushd .
    
    while [ ! -f "$file" ]
    do
        if [ "$(pwd)" != "/" ]
         then
            cd ..
        else
            failure=true
            break
        fi
    done
    
    if [ -z "$failure" ]
      then
        echo Found file in $(pwd) 
        # Your command!
        composer show -i | grep "laravel/framework"
        popd
    else
        echo File $file could not be found! >&2
        popd
        exit 1
    fi
    
    exit 0
    
  2. 另一种选择是保存一个变量,该变量保存我们目前到达的目录。这将允许在根本不改变目录的情况下搜索文件!

    file=composer.lock
    unset failure
    cpath=$(pwd)
    
    while [ ! -f "$cpath/$file" ]
    do
        if [ "$cpath" != "/" ]
         then
            cpath=$(cd $cpath/.. && pwd)
        else
            failure=true
            break
        fi
    done
    
    if [ -z "$failure" ]
      then
        echo Found file in: $cpath
        # do something with $cpath ... 
    else
        echo File $file could not be found! >&2
        exit 1
    fi
    
    exit 0
    

它适用于 shbash。由于我没有安装 zsh,我无法在 zsh 中试用它,但我认为它也应该在那里工作。不过我不确定 如果您愿意,可以省略 echo Found file in $(pwd)。我把它放在那里用于测试目的

祝你好运