Полный путь к сценарию TCSH - PullRequest
0 голосов
/ 23 августа 2011

В оболочке 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.

Ответы [ 2 ]

2 голосов
/ 29 апреля 2013

Если ваш csh-скрипт называется test.csh, тогда это будет работать:

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

0 голосов
/ 24 августа 2011

Я не использую 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 нет, поэтому отправная точка для фрагмента скрипта в вопросе отсутствует. Таким образом, если я не пропустил что-то в руководстве или руководство не является полным, то простого способа достижения того же результата в 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]})
...