在 CWD 或其父级中查找文件

在 CWD 或其父级中查找文件

我正在尝试为经常输入的命令创建别名。因为我正在开发一个基于 Laravel 的大型项目,所以我需要经常使用命令行工具 artisan。但是,我通常不想在根目录中使用该文件。

我通常不需要递归向上在我编写的脚本中,所以我有点迷茫。我的第一个想法是尝试使用类似命令find . -name artisan,如果它找不到任何内容,则cd ..再次检查直到当前工作目录为/。然后我希望能够将参数从 shell 脚本传递给最终找到的 artisan 副本。

是否有一个 linux/unix/osx 终端实用程序/约定可以解决这个问题?

编辑:

抱歉,我之前应该说清楚这一点的,但是我没有考虑到这一点。

artisan是一个 CLI 界面LaravelPHP 框架。我使用的是版本 3,但如果我用它启动另一个项目,我可能会使用版本 4。这两个版本之间存在许多重大变化,但更重要的是,artisan项目根目录中的脚本只是框架内代码的引导脚本。

例如,因为它对引用具有本地的、版本敏感的依赖关系paths.php,这告诉它其他资源在哪里,比如框架本身,所以我认为我不能将它移动到bin目录并符号链接到它。

是的,我可以从子目录向下链接到脚本,但我正在寻找比这更自动化的东西。例如,Git 如何从子目录中找到存储库目录?我知道它必须在树中向上递归才能找到它,但由于它在 CI 中,我不知道如何找到它,或者在 Shell/Bash 脚本中实现它。

答案1

您可以在当前目录中查找该文件,如果未找到,则在文件系统中向上查找,直到找到该文件或到达根目录。例如:

#!/bin/bash

wanted=$1

dir=.
while [[ ! -x "$dir/$wanted" ]]; do
    if [[ "$dir" -ef "../$dir" ]]; then
        echo "Could not find '$wanted'." 1>&2
        exit 2
    fi
    dir="../$dir"
done

echo "Found '$dir/$wanted'."

在这里,我们注意到 . 和 .. 指的是同一个目录,从而检测到我们已经到达根目录。

答案2

谢谢Mavit 的回答斯科特的评论,我想到了一个不错的解决方案。我在 Mac OS X 10.6.8 上使用了它,但它应该非常便携。

#!/bin/bash

wanted=$(basename $0)

dir=.
while [[ ! -x "$dir/$wanted" ]]; do
    if [[ "$dir" -ef "../$dir" ]]; then
        echo "$wanted is not in the current directory or any of its parents" 1>&2
        exit 2
    fi

    dir="../$dir"
done

# Find the absolute path to the command
dir=$(cd -- "$dir" && pwd)

if [[ "$dir/$wanted" -ef "$0" ]]; then
    echo "Cannot call self."
    exit 2
fi

# Execute the command and pass in $1... parameters to it.
exec "$dir/$wanted" "$@"

答案3

如果您正在寻找一个特定的命令(并且您知道它应该在哪里),为什么不使用完整路径来调用它/usr/local/bin/path/to/artisan,或者将 artisan 的目录添加到您的 PATH 变量中。

相关内容