我正在尝试为经常输入的命令创建别名。因为我正在开发一个基于 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 变量中。