1

在 bash shell 中,即使脚本由源、链接、./... 等调用,我也可以获得脚本的完整路径。这些神奇的 bash 行:

 #Next lines just find the path of the file.
 #Works for all scenarios including:
 #when called via multiple soft links.
 #when script called by command "source" aka . (dot) operator.
 #when arg $0 is modified from caller.
 #"./script" "/full/path/to/script" "/some/path/../../another/path/script" "./some/folder/script"
 #SCRIPT_PATH is given in full path, no matter how it is called.
 #Just make sure you locate this at start of the script.
 SCRIPT_PATH="${BASH_SOURCE[0]}";
 if [ -h "${SCRIPT_PATH}" ]; then
   while [ -h "${SCRIPT_PATH}" ]; do SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done
 fi
 pushd `dirname ${SCRIPT_PATH}` > /dev/null
 SCRIPT_PATH=`pwd`;
 popd  > /dev/null

如何在 TCSH shell 中获取相同条件下的脚本路径?这些“魔法线”是什么?

PS这不是这个问题和类似问题的重复。我知道$0

4

2 回答 2

2

如果您的 csh 脚本被命名为 test.csh,那么这将起作用:

/usr/sbin/lsof +p $$ | \grep -oE /.\*test.csh

于 2013-04-29T16:03:32.590 回答
0

我不使用tcsh也不声称其中的大师身份,或任何其他 C shell 变体。我也坚信Csh Programming Considered Harmful包含很多道理;我使用 Korn shell 或 Bash。

但是,我可以查看手册页,并且我使用了 tcsh 的手册页(tcsh 6.17.00 (Astron) 2009-07-10 (x86_64-apple-darwin)在 MacOS 10.7.1 Lion 上)。

据我所见,没有变量${BASH_SOURCE[0]}in的类似物tcsh,因此问题中脚本片段的起点缺失。因此,除非我遗漏了手册中的某些内容,或者手册不完整,否则没有简单的方法可以在tcsh.

如评论中所述,原始脚本片段也存在一些问题。/home/user1如果脚本是使用 name调用当前目录/usr/local/bin/xyz,但这是一个包含 的符号链接../libexec/someprog/executable,那么代码片段将产生错误的答案(它可能会说/home/user1因为目录/home/libexec/someprog不存在)。

while此外,将循环包装在 anif中是没有意义的。代码应该只包含while循环。

SCRIPT_PATH="${BASH_SOURCE[0]}";
while [ -h "${SCRIPT_PATH}" ]; do SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done

您应该查找该realpath()功能;甚至可能有一个使用它的命令已经可用。编写一个使用realpath(). 但是,据我所知,标准的 Linux 命令都没有包装该realpath()函数,这很遗憾,因为它可以帮助您解决问题。(特别是statandreadlink命令没有帮助。)

在最简单的情况下,您可以编写一个使用realpath()如下的程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

int main(int argc, char **argv)
{
    int rc = EXIT_SUCCESS;
    for (int i = 1; i < argc; i++)
    {
        char *rn = realpath(argv[i], 0);
        if (rn != 0)
        {
            printf("%s\n", rn);
            free(rn);
        }
        else
        {
            fprintf(stderr, "%s: failed to resolve the path for %s\n%d: %s\n",
                    argv[0], argv[i], errno, strerror(errno));
            rc = EXIT_FAILURE;
        }
    }
    return(rc);
}

如果调用了该程序realpath,则 Bash 脚本片段将简化为:

SCRIPT_PATH=$(realpath ${BASH_SOURCE[0]})
于 2011-08-24T06:43:49.440 回答