9

我有一个源代码树,其根位于类似/home/me/workspace. 有许多子目录很多层次。特别是有一个包含一些工具的路径:

/home/me/workspace/tools/scripts

我正在编写一个 bash 函数,我可以从树中传递字符串的任何位置调用它tools/scripts。该函数应该从当前工作目录迭代/查找路径片段tools/scripts,然后如果找到它,则打印出找到它的绝对路径。在本例中,/home/me/workspace将被打印。如果根本找不到路径片段,则不打印任何内容。

我已经有以下 bash 函数可以为我执行此操作:

search_up ()
(
    while [ $PWD != "/" ]; do
        if [ -e "$1" ]; then
            pwd
            break
        fi
        cd ..
    done
)

但这似乎有点啰嗦。我想知道是否有任何其他方法可以在 bash 本身或单个find命令或任何其他常见实用程序中执行此操作。我特别注重可读性和简洁性。

注意我不是在寻找整个树的完整递归搜索。

我的 bash 也不是最新的,所以请不要使用最新的、最好的技巧:

$ bash --version
GNU bash, version 3.00.15(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2004 Free Software Foundation, Inc.
$
4

2 回答 2

4

作为记录,这是我最终使用的:

while [ $PWD != "/" ]; do test -e tools/bin && { pwd; break; }; cd .. ; done

与我的 OP 类似,但最后我能够完全删除子shell 括号 (),因为这一行本身是使用另一个程序的“shell”命令调用的。因此也将它们全部塞到一条线上。

我仍然喜欢 KonsoleBox 的合理答案,因为它可能是一个更通用的解决方案,所以我接受了。

于 2013-10-10T14:41:14.210 回答
4

这应该可以,但告诉我它是否需要与 POSIX 兼容。这样做的好处是您不需要为了进行搜索而将目录更改为更高级别,也不需要使用子shell。

#!/bin/bash

search_up() {
    local look=${PWD%/}

    while [[ -n $look ]]; do
        [[ -e $look/$1 ]] && {
            printf '%s\n' "$look"
            return
        }

        look=${look%/*}
    done

    [[ -e /$1 ]] && echo /
}

search_up "$1"

例子:

bash script.sh /usr/local/bin

输出:

/
于 2013-09-25T17:37:20.360 回答