Intereting Posts
Как напечатать самое длинное число в строке? Sudo su issue на ubuntu 14.04 lts: / root / zsh не может быть найден Что означает это правило iptables? Почему bash интерпретирует символы, которые у меня есть? LibreOffice представляет случайные разрывы страниц переименование нескольких файлов путем удаления случайных чисел скопировать + вставить между рабочим столом Linux и vmware? Отображение кнопки Xinput и эмуляция средней кнопки сохранять те же метаданные inodes с помощью rsync или игнорировать метаданные с помощью du Почему записи NS постоянно меняются? Перенаправление всего IP-трафика через USB-порт на фиксированный адрес Значок по умолчанию для значков состояния строки состояния do_posix_clock_monotonic_gettime отсутствует в linux / time.h Можете ли вы изменить цель динамической ссылки без перекомпиляции? Как преобразовать PDF в 4-up в ландшафтном режиме (в идеале с использованием ghostscript)?

Как создать скрипт, который использует $ 0, когда он находится на $ PATH?

У меня есть сценарий (~ /…/ gremlin), который я создал софт-ссылку для:

ln -s ~/[...]/gremlin ~/sc/gremlin 

~/sc/gremlin находится в $PATH .
Вызов сценария напрямую работает.
Вызывать его по ссылке нет.
Он использует dirname $0 поэтому он ничего не получает.

Есть ли способ сделать эту работу без изменения сценария и без создания другой вместо мягкой ссылки?

Вот как используется $ 0:

 case `uname` in CYGWIN*) CP=$( echo `dirname $0`/../lib/*.jar . | sed 's/ /;/g') ;; *) CP=$( echo `dirname $0`/../lib/*.jar . | sed 's/ /:/g') esac 

Является ли использование dirname $0 проблемой или нет, будет зависеть от того, как он используется. Без более подробной информации мы не можем ответить на это.

Если (a) использование dirname $0 является проблемой и (b) вы не можете изменить сценарий, то решение должно заменить программную ссылку ~/sc/gremlin на скрипт:

 #!/bin/sh exec ~/../gremlin "$@" 

Таким образом, ~/../gremlin будет работать с правильным $0 .

Использование exec означает, что процесс, запускающий скрипт ~/../gremlin , заменит процесс, запущенный ~/sc/gremlin . Это более эффективно, если поддерживать оба процесса до тех пор, пока ~/../gremlin завершится.

Если вы хотите получить каталог ~/... из $0 , в отличие от ~/sc из сценария, вы можете сделать:

Если это zsh скрипт:

 #! /bin/zsh - dir=$0:A:h 

В противном случае и при условии, что у вас есть команда readlink которая ведет себя как GNU (некоторые системы имеют команду realpath которую вы можете использовать вместо realpath ):

 #! /bin/sh - dir=$(dirname -- "$(readlink -f -- "$0")") 

readlink -f и $0:A дает вам канонический путь к файлу, который является абсолютным путем после разрешения всех символических ссылок во всех компонентах пути.

А потом:

 set -- "$dir"/../lib/*.jar . case $(uname) in CYGWIN*) IFS=';';; *) IFS=:;; esac CP="$*" 

Или:

 case $(uname) in CYGWIN*) sep=';';; *) sep=:;; esac CP=$(printf "%s$sep" "$dir"/../lib/*.jar). 

Как отметил @ john1024, опечатка в вопросе OP может быть вопросом:

 ln -s ~/.../gremlin ~/sc/gremlin 

Хотя несколько приложений отмечают тройные точки, файловые системы Unix этого не делают. Ваша оболочка расширяет ~ (тильда), а не ln , поэтому

  ln -s ~/../gremlin ~/sc/gremlin 

будет расширять путь, как ожидалось. Если ссылка уже существует, ее можно перезаписать с помощью опции -f . Однако, если цель является фактическим файлом, опция -f будет молча перезаписывать файл с символической ссылкой. Возможно, вы захотите использовать опцию -i которая, по крайней мере, говорит вам, что есть что-то уже там.

Если вы хотите проверить ссылку (доказать, что она указывает на файл), опция -L ls полезна:

 ls -lL ~/sc/gremlin 

Если это не файл, ls (в зависимости от реализации) отображает только l для типа (первый символ списка), с вопросительными знаками для битов разрешения) или каким-либо другим признаком того, что он не указывает на реального файла (OSX просто отказывается показывать что-либо вообще в этом случае, хотя он подсчитывает размер символической ссылки в общей сумме).

Дальнейшее чтение:

  • Шаблоны с тремя точками
  • Что случилось с возможностью использовать … (три точки), чтобы обратиться к директории grandparent?
  • 4.5.1 Символ подстановочного символа (особенность VMS 1980-х годов)