Эквивалент% ~ dp0 в ш - PullRequest
       47

Эквивалент% ~ dp0 в ш

14 голосов
/ 16 октября 2008

Я конвертирую некоторые командные файлы Windows в сценарии Unix, используя sh. У меня проблемы, потому что некоторые действия зависят от макроса% ~ dp0, доступного в пакетных файлах.

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

Ответы [ 8 ]

7 голосов
/ 16 октября 2008

Проблема (для вас) с $0 состоит в том, что для нее задана любая командная строка, использованная для вызова скрипта, а не местоположение самого скрипта. Это может затруднить получение полного пути к каталогу, содержащему скрипт, который вы получите из %~dp0 в пакетном файле Windows.

Например, рассмотрим следующий скрипт: dollar.sh:

#!/bin/bash
echo $0

Если вы запустите его, вы получите следующий вывод:

# ./dollar.sh
./dollar.sh
# /tmp/dollar.sh
/tmp/dollar.sh

Таким образом, чтобы получить полное имя каталога скрипта, я делаю следующее:

cd `dirname $0`
SCRIPTDIR=`pwd`
cd -

Это работает следующим образом:

  1. cd к каталогу скрипта, используя относительный или абсолютный путь из командной строки.
  2. Получает абсолютный путь к этому каталогу и сохраняет его в SCRIPTDIR.
  3. Возвращается к предыдущему рабочему каталогу, используя "cd -".
3 голосов
/ 17 октября 2008

В bash под linux вы можете получить полный путь к команде с помощью:

readlink /proc/$$/fd/255

и получить каталог:

dir=$(dirname $(readlink /proc/$$/fd/255))

Это некрасиво, но мне еще предстоит найти другой путь.

2 голосов
/ 16 октября 2008

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

Я нашел обходной путь, который работает только в bash, $ BASH_SOURCE всегда содержит информацию о скрипте, на который он ссылается. Даже если сценарий получен, он правильно преобразован в исходный (исходный) сценарий.

2 голосов
/ 16 октября 2008

Да, вы можете! Это в аргументах. :)

посмотрите на

${0}

объединяя это с

{$var%Pattern}
Remove from $var  the shortest part of $Pattern that matches the back end of $var.

то, что вы хотите, это просто

${0%/*}

Я рекомендую Руководство по расширенному написанию сценариев Bash (это также откуда вышеприведенная информация). Особенная часть Преобразование командных файлов DOS в сценарии оболочки может быть полезно для вас. :)

Если я вас неправильно понял, возможно, вам придется объединить это с выводом "pwd". Поскольку он содержит только путь, по которому был вызван скрипт! Попробуйте следующий скрипт:

#!/bin/bash
called_path=${0%/*}
stripped=${called_path#[^/]*}
real_path=`pwd`$stripped
echo "called path: $called_path"
echo "stripped: $stripped"
echo "pwd: `pwd`"
echo "real path: $real_path

Это требует некоторой работы, хотя. Я рекомендую использовать подход Дейва Уэбба, если это невозможно.

1 голос
/ 29 августа 2017

Правильный ответ: Как определить местоположение моего скрипта? Я хочу прочитать некоторые файлы конфигурации из того же места.

Важно понимать, что в общем случае эта проблема не имеет решения . Любой подход, о котором вы могли слышать, и любой подход, который будет подробно описан ниже, имеет недостатки и будет работать только в определенных случаях. Прежде всего, постарайтесь полностью избежать этой проблемы, не завися от местоположения вашего скрипта!

Прежде чем мы углубимся в решения, давайте разберемся с некоторыми недоразумениями. Важно понимать, что: Ваш скрипт фактически не имеет местоположения ! Откуда бы ни приходили байты, для него не существует «одного канонического пути». Никогда. $ 0 НЕ является ответом на вашу проблему. Если вы думаете, что это так, вы можете либо перестать читать и написать больше ошибок, либо можете принять это и читать дальше. ...

0 голосов
/ 19 июня 2014

Это должно работать для оболочки bash:

dir=$(dirname $(readlink -m $BASH_SOURCE))

Тестовый скрипт:

#!/bin/bash
echo $(dirname $(readlink -m $BASH_SOURCE))

Выполнить тест:

$ ./somedir/test.sh 
/tmp/somedir
$ source ./somedir/test.sh 
/tmp/somedir
$ bash ./somedir/test.sh 
/tmp/somedir
$ . ./somedir/test.sh 
/tmp/somedir
0 голосов
/ 16 октября 2008

Я пробовал $ 0 раньше, а именно:

dirname $ 0

и он просто возвращает "." даже если сценарий получен из другого сценария:

. ../somedir/somescript.sh

0 голосов
/ 16 октября 2008

Попробуйте это:

${0%/*}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...