Эквивалент% ~ dp0 в sh
Я конвертирую некоторые пакетные файлы Windows в сценарии Unix, используя sh. У меня проблемы, потому что какое-то поведение зависит от макроса% ~ dp0, доступного в пакетных файлах.
Есть ли какой-либо sh эквивалент этого? Любой способ получить каталог, в котором живет исполняемый script?
Ответы
Ответ 1
Проблема (для вас) с $0
заключается в том, что она настроена на использование какой-либо командной строки для вызова script, а не местоположения самого script. Это может затруднить получение полного пути каталога, содержащего script, который вы получаете из %~dp0
в пакетном файле Windows.
Например, рассмотрим следующие script, dollar.sh
:
#!/bin/bash
echo $0
Если вы запустите его, вы получите следующий результат:
# ./dollar.sh
./dollar.sh
# /tmp/dollar.sh
/tmp/dollar.sh
Итак, чтобы получить полное имя каталога script, я делаю следующее:
cd `dirname $0`
SCRIPTDIR=`pwd`
cd -
Это работает следующим образом:
-
cd
в каталог script, используя либо относительный, либо абсолютный путь из командной строки.
- Получает абсолютный путь этого каталога и сохраняет его в
SCRIPTDIR
.
- Возврат к предыдущему рабочему каталогу с помощью "
cd -
".
Ответ 2
Я пытался найти путь для script, который был получен из другого script. И это была моя проблема, когда поиск текста просто копируется в вызывающий script, поэтому $0 всегда возвращает информацию о вызывающем script.
Я нашел обходной путь, который работает только в bash, $BASH_SOURCE всегда имеет информацию о script, в которой он упоминается. Даже если источник script найден правильно, он корректно разрешен исходным (sourced) script.
Ответ 3
В bash под Linux вы можете получить полный путь к команде с помощью:
readlink /proc/$$/fd/255
и получить каталог:
dir=$(dirname $(readlink /proc/$$/fd/255))
Это уродливо, но мне еще предстоит найти другой способ.
Ответ 4
Да, вы можете! Это в аргументах.:)
посмотрите
${0}
комбинируя это с
{$var%Pattern}
Remove from $var the shortest part of $Pattern that matches the back end of $var.
что вы хотите, просто
${0%/*}
Я рекомендую Расширенный Bash Руководство по разработке сценариев.
(то есть также, где указанная выше информация).
Специально для части Преобразование файлов DOS в файлы сценариев командной оболочки
может быть вам полезна.:)
Если я вас неправильно понял, вам, возможно, придется объединить это с выходом "pwd". Поскольку он содержит только путь, с которым вызывался script с!
Попробуйте выполнить script:
#!/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
Это требует некоторой работы.
Я рекомендую использовать подход Дейва Уэбба, если это невозможно.
Ответ 5
Правильный ответ таков:
Как определить местоположение моего script? Я хочу прочитать некоторые файлы конфигурации из того же места.
Важно понимать, что в общем случае эта проблема не имеет решения. Любой подход, о котором вы, возможно, слышали, и любой подход, который будет подробно описан ниже, имеет недостатки и будет работать только в конкретных случаях. Прежде всего, постарайтесь полностью избежать проблемы, не завися от расположения вашего script!
Прежде чем погрузиться в решения, позвольте прояснить некоторые недоразумения. Важно понимать, что: Ваш script фактически не имеет местоположения! Везде, где байты заканчиваются, для него нет "одного канонического пути". Никогда. $0 НЕ является ответом на вашу проблему. Если вы так думаете, вы можете либо перестать читать, либо писать больше ошибок, либо можете принять это и прочитать дальше....
Ответ 6
Я пробовал $0 раньше, а именно:
dirname $0
и он просто возвращает "." даже когда script используется другим script:
.../somedir/somescript.sh
Ответ 7
Это должно работать для оболочки bash:
dir=$(dirname $(readlink -m $BASH_SOURCE))
Тест script:
#!/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
Ответ 8
Попробуйте следующее:
${0%/*}