1

bash シェルでは、スクリプトがソース、リンク、./... などによって呼び出された場合でも、スクリプトのフル パスを取得できます。これらの魔法の 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 シェルで同じ条件でスクリプト パスを取得するにはどうすればよいですか? これらの「魔法の線」とは何ですか?

PSこれと同様の質問の複製ではありません。私は知ってい$0ます。

4

2 に答える 2

0

私はそれを使用tcshしておらず、教祖の地位を主張していません.Cシェルの他の変種も使用していません。また、有害と見なされる Csh プログラミングには多くの真実が含まれていると固く信じています。Korn シェルまたは Bash を使用します。

ただし、マニュアル ページを見ることはできます。tcsh のマニュアル ページを使用しました ( tcsh 6.17.00 (Astron) 2009-07-10 (x86_64-apple-darwin)MacOS 10.7.1 Lion)。

私が見る限り、 の変数${BASH_SOURCE[0]}に類似したものはないtcshため、質問のスクリプト フラグメントの開始点が欠落しています。したがって、マニュアルの何かを見逃したり、マニュアルが不完全でない限り、同じ結果を .NET で簡単に実現する方法はありません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()関数を調べる必要があります。すでに利用可能なそれを使用するコマンドさえあるかもしれません。を使用するコマンドを書くことは確かに難しくありません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);
}

そのプログラムが呼び出されrealpathた場合、Bash スクリプト フラグメントは次のように縮小されます。

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