Shell TCSH脚本完整路径

Shell TCSH脚本完整路径,shell,tcsh,Shell,Tcsh,在bashshell中,我可以获得脚本的完整路径,即使该脚本是由源代码、链接、./…等调用的。 这些神奇的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. #whe

在bashshell中,我可以获得脚本的完整路径,即使该脚本是由源代码、链接、./…等调用的。 这些神奇的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中获得相同条件下的脚本路径?这些“魔线”是什么


另外,这不是重复的问题和类似的问题。我知道
$0

我不使用
tcsh
,也不在其中声明guru状态,或任何其他C shell变体。我也坚信其中包含着很多真理;我使用kornshell或Bash

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

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


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

另外,如果
while
循环包装在
if
中是没有意义的;代码应该只包含
while
循环

SCRIPT_PATH="${BASH_SOURCE[0]}";
while [ -h "${SCRIPT_PATH}" ]; do SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done
您应该查找该函数;甚至可能已经有一个使用它的命令可用。编写一个使用
realpath()
的命令当然不难。但是,据我所知,没有任何标准的Linux命令包装
realpath()
函数,这很遗憾,因为它可以帮助您解决问题。(特别是
stat
readlink
命令没有帮助。)

最简单的方法是,您可以编写一个使用
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);
}

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


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

我完全同意你的观点。但我的目标是让用户的生活尽可能简单。如果他们可以运行“source-environment.csh”,那么对他们来说就很容易了TCSH要求是因为RHEL 6使用它作为用户的默认shell。如果您使用tsch只是因为它是默认shell,为什么不更改默认shell?因为它不是我的默认shell,它是用户的默认shell。您没有听说过有时会为用户开发一些东西吗?。如果通过当前目录
/home/user1
使用名称
/usr/local/bin/xyz
,但这是一个包含
。/libexec/someprog/executable
的符号链接,那么代码段将产生错误的答案(可能会说
/home/user1
,因为
/home/libexec/someprog/executable
不存在)。将
while
循环包装在
if
中是没有意义的;代码应该只包含
while
循环。您应该查找
realpath()
函数;甚至可能已经有一个使用它的命令可用。编写一个使用
realpath()的命令当然不难
。我几乎认为这太冒险了,因为我太努力地列出所有打开的文件,但实际上我发现我的普通用户没有打开太多的文件,搜索setup.csh也受到了足够的限制。这并不漂亮,但我找到的唯一解决方案是为那些拒绝与时俱进的顽固用户提供的切换到bash。
SCRIPT_PATH=$(realpath ${BASH_SOURCE[0]})