Основной ответ: допустимые 5.
или 5,
входы
этот код обрабатывает его (но в моем примере отрицательные числа запрещены):
/^[0-9]+([.,][0-9]{1,2})?$/;
результаты приведены ниже:
true => "0" / true => "0.00" / true => "0.0" / true => "0,00" / true => "0,0" / true => "1,2" true => "1.1" / true => "1" / true => "100" true => "100.00" / true => "100.0" / true => "1.11" / true = > "1,11" / false => "-5" / false => "-0.00" / true => "101" / false => "0.00.0" / true => "0.000" / true => " 000.25 "/ false =>" .25 "/ true =>" 100.01 "/ true =>" 100.2 "/ true =>" 00 "/ false =>" 5. " / false => "6," / true => "82" / true => "81,3" / true => "7" / true => "7.654"
blockquote>
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
полезная острота, которая даст Вам полное имя каталога сценария, неважно, откуда это называют.
Это будет работать пока последний компонент пути, используемого, чтобы найти, что сценарий не является символьной ссылкой (ссылки каталога в порядке). Если Вы также хотите разрешить какие-либо ссылки на сам сценарий, Вам нужно многострочное решение:
#!/bin/bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
Этот последний будет работать с любой комбинацией псевдонимов, source
, bash -c
, символьные ссылки, и т.д.
Остерегаются: если Вы cd
к различному каталогу прежде, чем выполнить этот отрывок, результат может быть неправильным!
кроме того, не упустите $CDPATH
глюки , и выходные побочные эффекты stderr, если пользователь энергично переопределил CD для перенаправления вывода к stderr вместо этого (включая escape-последовательности, такой, звоня update_terminal_cwd >&2
на Mac). При добавлении >/dev/null 2>&1
в конце Вашего cd
команда будет заботиться об обеих возможностях.
, Чтобы понять, как это работает, попытайтесь выполнить это больше подробной формы:
#!/bin/bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
TARGET="$(readlink "$SOURCE")"
if [[ $TARGET == /* ]]; then
echo "SOURCE '$SOURCE' is an absolute symlink to '$TARGET'"
SOURCE="$TARGET"
else
DIR="$( dirname "$SOURCE" )"
echo "SOURCE '$SOURCE' is a relative symlink to '$TARGET' (relative to '$DIR')"
SOURCE="$DIR/$TARGET" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
fi
done
echo "SOURCE is '$SOURCE'"
RDIR="$( dirname "$SOURCE" )"
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
if [ "$DIR" != "$RDIR" ]; then
echo "DIR '$RDIR' resolves to '$DIR'"
fi
echo "DIR is '$DIR'"
И это распечатает что-то как:
SOURCE './scriptdir.sh' is a relative symlink to 'sym2/scriptdir.sh' (relative to '.')
SOURCE is './sym2/scriptdir.sh'
DIR './sym2' resolves to '/home/ubuntu/dotfiles/fo fo/real/real1/real2'
DIR is '/home/ubuntu/dotfiles/fo fo/real/real1/real2'
Использовать dirname "$0"
:
#!/bin/bash
echo "The script you are running has basename `basename "$0"`, dirname `dirname "$0"`"
echo "The present working directory is `pwd`"
использование pwd
один не будет работать, если Вы не запустите скрипт из каталога, он содержится в.
[matt@server1 ~]$ pwd
/home/matt
[matt@server1 ~]$ ./test2.sh
The script you are running has basename test2.sh, dirname .
The present working directory is /home/matt
[matt@server1 ~]$ cd /tmp
[matt@server1 tmp]$ ~/test2.sh
The script you are running has basename test2.sh, dirname /home/matt
The present working directory is /tmp
pwd
может использоваться для нахождения текущего рабочего каталога, и dirname
для нахождения каталога конкретного файла (команда, которая была выполнена, $0
, так dirname $0
должен дать Вам каталог текущего сценария).
Однако dirname
дает точно часть каталога имени файла, которое более вероятно, чем не будет относительно текущего рабочего каталога. Если Ваш сценарий должен изменить каталог по некоторым причинам, то вывод от dirname
становится бессмысленным.
Я предлагаю следующее:
#!/bin/bash
reldir=`dirname $0`
cd $reldir
directory=`pwd`
echo "Directory is $directory"
Таким образом, Вы получаете абсолют, скорее затем относительный каталог.
Так как скрипт будет запущен в отдельном экземпляре удара, нет никакой потребности восстановить рабочий каталог впоследствии, но если Вы действительно хотите возвратиться в своем сценарии по некоторым причинам, можно легко присвоить значение pwd
к переменной перед изменением каталога, для будущего использования.
Хотя просто
cd `dirname $0`
решает определенный сценарий в вопросе, я нахожу наличие полного пути к более более полезному обычно.
Я не думаю, что это столь легко, как другие разобрали его, чтобы быть. pwd не работает, поскольку текущий dir является не обязательно каталогом со сценарием. 0$ не всегда имеют информацию также. Рассмотрите следующие три способа вызвать сценарий.
./script
/usr/bin/script
script
первыми и третьими способами 0$ не имеют информации о полном пути Во втором, и третье, pwd не работают. Единственный способ получить dir третьим путем состоял бы в том, чтобы пробежать путь и найти файл с корректным соответствием. В основном код должен был бы восстановить то, что делает ОС.
Один способ сделать, что Вы спрашиваете, был бы только к hardcode данные в/usr/share dir и сослался бы на него полным путем. Данные shoudn't быть в/usr/bin dir так или иначе, таким образом, это, вероятно, нужно.
#!/bin/sh
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
PRG=`readlink "$PRG"`
done
scriptdir=`dirname "$PRG"`
Можно использовать $BASH_SOURCE
#!/bin/bash
scriptdir=`dirname "$BASH_SOURCE"`
Примечание, что необходимо использовать #!/bin/bash и не #!/bin/sh, так как это - расширение удара
Это работает в ударе 3.2:
path="$( dirname "$( which "$0" )" )"
Вот пример его использования:
Скажите, что у Вас есть ~ / каталог bin, который находится в Вашем $PATH. У Вас есть сценарий внутренняя часть этот каталог. Это получает сценарий ~/bin/lib/B. Вы знаете, где включенный сценарий относительно исходного (lib подкаталога), но не, где это относительно текущего каталога пользователя.
Это решено следующим (внутри A):
source "$( dirname "$( which "$0" )" )/lib/B"
Не имеет значения, где пользователь или как он называет сценарий, это будет всегда работать.
Хм, если в базовом имени пути & dirname просто не собираются сокращать его и идут, путь тверд (что, если родитель не экспортировал ПУТЬ!). Однако оболочка должна иметь открытый дескриптор к своему сценарию, и в ударе дескриптор является работами № 255.
SELF=`readlink /proc/$/fd/255`
для меня.
Я обычно делаю:
LIBDIR=$(dirname "$(readlink -f "$(type -P $0 || echo $0)")")
source $LIBDIR/lib.sh
Это - конкретный Linux, но Вы могли использовать:
SELF=$(readlink /proc/$/fd/255)
pushd . > /dev/null
SCRIPT_PATH="${BASH_SOURCE[0]}"
if ([ -h "${SCRIPT_PATH}" ]); then
while([ -h "${SCRIPT_PATH}" ]); do cd `dirname "$SCRIPT_PATH"`;
SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done
fi
cd `dirname ${SCRIPT_PATH}` > /dev/null
SCRIPT_PATH=`pwd`;
popd > /dev/null
Работы для всех версий, включая
source
"иначе .
(точечный) оператор. $0
изменяется от вызывающей стороны. "./script"
"/full/path/to/script"
"/some/path/../../another/path/script"
"./some/folder/script"
С другой стороны, если сам сценарий удара является относительной символьной ссылкой, Вы хотите следовать за ним и возвратить полный путь связанного - к сценарию:
pushd . > /dev/null
SCRIPT_PATH="${BASH_SOURCE[0]}";
if ([ -h "${SCRIPT_PATH}" ]) then
while([ -h "${SCRIPT_PATH}" ]) do cd `dirname "$SCRIPT_PATH"`; SCRIPT_PATH=`readlink "${SCRIPT_PATH}"`; done
fi
cd `dirname ${SCRIPT_PATH}` > /dev/null
SCRIPT_PATH=`pwd`;
popd > /dev/null
SCRIPT_PATH
дан в полном пути, неважно, как это называют.
Просто удостоверьтесь, что Вы определяете местоположение этого в начале сценария.
Этот Копилефт комментария и кода, выбираемая лицензия под GPL2.0 или позже или CC-SA 3.0 (Доля CreativeCommons Одинаково) или позже. (c) 2008.Все права защищены. Никакая гарантия любого вида. Вас предупредили.
http://www.gnu.org/licenses/gpl-2.0.txt
http://creativecommons.org/licenses/by-sa/3.0/
18eedfe1c99df68dc94d4a94712a71aaa8e1e9e36cacf421b9463dd2bbaa02906d0d6656
Я хочу удостовериться, что сценарий работает в его каталоге. Так
cd $(dirname $(which $0) )
После этого если Вы действительно хотите знать, куда Вы работают, затем выполняет команду ниже.
DIR=$(/usr/bin/pwd)
Можно сделать это просто объединение названия сценария ([112]
) с realpath
и/или dirname
. Это работает на Bash и Shell.
#!/usr/bin/env bash
RELATIVE_PATH="[110]"
RELATIVE_DIR_PATH="$(dirname "[110]")"
FULL_DIR_PATH="$(realpath "[110]" | xargs dirname)"
FULL_PATH="$(realpath "[110]")"
echo "RELATIVE_PATH->${RELATIVE_PATH}<-"
echo "RELATIVE_DIR_PATH->${RELATIVE_DIR_PATH}<-"
echo "FULL_DIR_PATH->${FULL_DIR_PATH}<-"
echo "FULL_PATH->${FULL_PATH}<-"
вывод будет чем-то вроде этого:
# RELATIVE_PATH->./bin/startup.sh<-
# RELATIVE_DIR_PATH->./bin<-
# FULL_DIR_PATH->/opt/my_app/bin<-
# FULL_PATH->/opt/my_app/bin/startup.sh<-
0$ название самого сценария
https://www.tldp.org/LDP/abs/html/othertypesv.html
пример: https://gist.github.com/LozanoMatheus/da96b4e44b89b13ad4af10ac4602ad99
Это - то, что я обработал в течение лет для использования в качестве заголовка на моих сценариях удара:
## BASE BRAIN - Get where you're from and who you are.
MYPID=$
ORIGINAL_DIR="$(pwd)" # This is not a hot air balloon ride..
fa="[110]" # First Assumption
ta= # Temporary Assumption
wa= # Weighed Assumption
while true; do
[ "${fa:0:1}" = "/" ] && wa=[110] && break
[ "${fa:0:2}" = "./" ] && ta="${ORIGINAL_DIR}/${fa:2}" && [ -e "$ta" ] && wa="$ta" && break
ta="${ORIGINAL_DIR}/${fa}" && [ -e "$ta" ] && wa="$ta" && break
done
SW="$wa"
SWDIR="$(dirname "$wa")"
SWBIN="$(basename "$wa")"
unset ta fa wa
( [ ! -e "$SWDIR/$SWBIN" ] || [ -z "$SW" ] ) && echo "I could not find my way around :( possible bug in the TOP script" && exit 1
в этой точке Ваш SW переменных SWDIR и SWBIN содержат то, в чем Вы нуждаетесь.
Команда dirname является самой простой, просто анализируя путь до имени файла из Переменная $ 0 (имя сценария):
dirname "$0"
Но, как указал matt b , возвращаемый путь отличается в зависимости от того, как вызывается сценарий. pwd не выполняет эту работу, потому что он сообщает вам только текущий каталог, а не каталог, в котором находится сценарий. Кроме того, если выполняется символическая ссылка на сценарий, вы получите (возможно, относительный) путь туда, где находится ссылка, а не на сам скрипт.
Некоторые другие упоминали команду readlink , но в самом простом случае вы можете использовать:
dirname "$(readlink -f "$0")"
readlink преобразует путь скрипта в абсолютный путь от корня файловой системы. Таким образом, любые пути, содержащие одинарные или двойные точки, тильды и / или символические ссылки, будут преобразованы в полный путь.
Вот сценарий, демонстрирующий каждый из них, whatdir.sh:
#!/bin/bash
echo "pwd: `pwd`"
echo "\$0: $0"
echo "basename: `basename $0`"
echo "dirname: `dirname $0`"
echo "dirname/readlink: $(dirname $(readlink -f $0))"
Запуск этого сценария в моем home dir, используя относительный путь:
>>>$ ./whatdir.sh
pwd: /Users/phatblat
$0: ./whatdir.sh
basename: whatdir.sh
dirname: .
dirname/readlink: /Users/phatblat
Опять же, но используя полный путь к сценарию:
>>>$ /Users/phatblat/whatdir.sh
pwd: /Users/phatblat
$0: /Users/phatblat/whatdir.sh
basename: whatdir.sh
dirname: /Users/phatblat
dirname/readlink: /Users/phatblat
Теперь меняем каталоги:
>>>$ cd /tmp
>>>$ ~/whatdir.sh
pwd: /tmp
$0: /Users/phatblat/whatdir.sh
basename: whatdir.sh
dirname: /Users/phatblat
dirname/readlink: /Users/phatblat
И, наконец, используя символическую ссылку для выполнения сценария:
>>>$ ln -s ~/whatdir.sh whatdirlink.sh
>>>$ ./whatdirlink.sh
pwd: /tmp
$0: ./whatdirlink.sh
basename: whatdirlink.sh
dirname: .
dirname/readlink: /Users/phatblat
Небольшая доработка решения e-satis и 3bcdnlklvc04a указали в их ответ
SCRIPT_DIR=''
pushd "$(dirname "$(readlink -f "$BASH_SOURCE")")" > /dev/null && {
SCRIPT_DIR="$PWD"
popd > /dev/null
}
. Это должно работать во всех перечисленных ими случаях.
РЕДАКТИРОВАТЬ: запретить popd после неудачного pushd, благодаря konsolebox
Это единственный способ, который я нашел, чтобы сказать надежно:
SCRIPT_DIR=$(dirname $(cd "$(dirname "$BASH_SOURCE")"; pwd))
Я хочу прокомментировать предыдущий ответ там ( https://stackoverflow.com/a/201915/5010054), но не имею достаточной репутации, чтобы сделать это.
Найденный решением для этого два года назад на сайте документации яблока: https://developer.apple.com/library/archive/documentation/OpenSource/Conceptual/ShellScripting/AdvancedTechniques/AdvancedTechniques.html . И я придерживался этого метода впоследствии. Это не может обработать гибкую ссылку, но иначе работает вполне прилично на меня. Я отправляю его здесь для любого, кому нужен он и как запрос комментария.
#!/bin/sh
# Get an absolute path for the poem.txt file.
POEM="$PWD/../poem.txt"
# Get an absolute path for the script file.
SCRIPT="$(which [110])"
if [ "x$(echo $SCRIPT | grep '^\/')" = "x" ] ; then
SCRIPT="$PWD/$SCRIPT"
fi
Как показано кодом, после того, как Вы получите полный путь сценария, тогда можно использовать команду dirname для получения пути каталога.
правовая оговорка - главный ответ не работает во всех случаях... вот почему отправляющих этот альтернативный ответ.
, поскольку у меня были проблемы с BASH_SOURCE с включенным подходом 'CD' к некоторым очень новым и также к менее новой установленной Ubuntu, Гостеприимной (16.04) системы при вызове сценария оболочки посредством "sh my_script.sh", я испытал что-то другое, что на данный момент, кажется, работает вполне гладко за моими целями. Подход немного более компактен в сценарии и является дальнейшим намного меньшим загадочным чувством.
этот альтернативный подход использует внешние приложения 'realpath' и ''dirname от coreutils пакета. (хорошо, не любому нравятся издержки вызова вторичного processe - но видя, что сценарии мультилинии для разрешения истинного объекта это привычка, что плохо любой имеющий его решает в единственном двоичном использовании.)
так позволяет, см. один пример тех альтернативное решение для описанной задачи запросов истинного полного пути к определенный файл:
SCRIPT=`realpath -s [110]`
SCRIPTPATH=`dirname $SCRIPT`
Или при наличии шанса использования путей с пробелами (или возможно другие специальные символы):
SCRIPT=`realpath -s "[111]"`
SCRIPTPATH=`dirname "$SCRIPT"`
действительно, если Вам не нужно значение переменной СЦЕНАРИЯ затем, Вы смогли объединять это с двумя лайнерами даже в одну строку. но почему действительно необходимо потратить усилие для этого?
/tmp/a/b/c $ . ./test.sh
/tmp/a/b/c
/tmp/a/b/c $ . /tmp/a/b/c/test.sh
/tmp/a/b/c
/tmp/a/b/c $ ./test.sh
/tmp/a/b/c
/tmp/a/b/c $ /tmp/a/b/c/test.sh
/tmp/a/b/c
/tmp/a/b/c $ cd
~ $ . /tmp/a/b/c/test.sh
/tmp/a/b/c
~ $ . ../../tmp/a/b/c/test.sh
/tmp/a/b/c
~ $ /tmp/a/b/c/test.sh
/tmp/a/b/c
~ $ ../../tmp/a/b/c/test.sh
/tmp/a/b/c
#!/usr/bin/env bash
# snagged from: https://stackoverflow.com/a/51264222/26510
function toAbsPath {
local target
target="$1"
if [ "$target" == "." ]; then
echo "$(pwd)"
elif [ "$target" == ".." ]; then
echo "$(dirname "$(pwd)")"
else
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"
fi
}
function getScriptDir(){
local SOURCED
local RESULT
(return 0 2>/dev/null) && SOURCED=1 || SOURCED=0
if [ "$SOURCED" == "1" ]
then
RESULT=$(dirname "$1")
else
RESULT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
fi
toAbsPath "$RESULT"
}
SCRIPT_DIR=$(getScriptDir "[111]")
echo "$SCRIPT_DIR"
ME=`type -p $0`
MDIR="${ME%/*}"
WORK_DIR=$(cd $MDIR && pwd)
function getScriptAbsoluteDir { # fold>>
# @description used to get the script path
# @param $1 the script $0 parameter
local script_invoke_path="$1"
local cwd=`pwd`
# absolute path ? if so, the first character is a /
if test "x${script_invoke_path:0:1}" = 'x/'
then
RESULT=`dirname "$script_invoke_path"`
else
RESULT=`dirname "$cwd/$script_invoke_path"`
fi
} # <<fold
This means that we need two separate NSPersistentStoreCoordinators, each of them having it's own NSManagedObjectContext.
– Arek Holko 14 October 2013 в 07:31