2011-08-23 215 views
0

在bash shell中,我可以得到一個即使腳本是由源,鏈接,調用的腳本的完整路徑/ ...等 這些神奇的bash行:TCSH腳本完整路徑

#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中的相同條件下獲得腳本路徑?這些'魔術線'是什麼?

P.S.它不是this和類似問題的重複。我知道$0

+3

[如果您可以避免腳本在tcsh中,您應該。](http://www.grymoire.com/Unix/CshTop10.txt) – Johnsyweb

+0

我絕對同意你的看法。但我的目標是讓用戶的生活儘可能簡單。如果他們可以從任何地方運行「source environment.csh」,他們很容易。 TCSH需求是因爲RHEL 6將其用作用戶的默認外殼。 – MajesticRa

+0

如果您使用tsch僅僅是因爲它是默認的shell,爲什麼不更改默認的shell呢? – carlpett

回答

0

我沒有使用tcsh,也沒有聲明guru的狀態,或者其他C shell的變種。我也堅信Csh Programming Considered Harmful包含很多事實;我使用Korn shell或Bash。

但是,我可以查看手冊頁,並使用tcsh的手冊頁(MacOS 10.7.1 Lion上的tcsh 6.17.00 (Astron) 2009-07-10 (x86_64-apple-darwin))。

據我所見,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()函數;甚至可能會有一個使用它的命令。編寫一個確實使用realpath()的命令當然不難。但是,據我所知,沒有任何標準的Linux命令包裝realpath()函數,這很遺憾,因爲它可以幫助您解決問題。 (該statreadlink命令沒有幫助,特別是。)

簡單地說,你可以寫一個使用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]}) 
0

如果你的CSH腳本名爲test.csh,那麼這將工作:

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