В основном мне нужно запустить script с помощью путей, связанных с расположением файла оболочки script, как я могу изменить текущий каталог в тот же каталог, где находится файл script?
Unix shell script узнать, в какой папке находится файл script?
Ответ 1
В Bash вы должны получить то, что вам нужно вот так:
#!/usr/bin/env bash
BASEDIR=$(dirname "$0")
echo "$BASEDIR"
Ответ 2
Исходное сообщение содержит решение (игнорируйте ответы, они не добавляют ничего полезного). Интересную работу выполняет упомянутая команда unix readlink
с опцией -f
. Работает, когда script вызывается как абсолютным, так и относительным путем.
Для bash, sh, ksh:
#!/bin/bash
# Absolute path to this script, e.g. /home/user/bin/foo.sh
SCRIPT=$(readlink -f "$0")
# Absolute path this script is in, thus /home/user/bin
SCRIPTPATH=$(dirname "$SCRIPT")
echo $SCRIPTPATH
Для tcsh, csh:
#!/bin/tcsh
# Absolute path to this script, e.g. /home/user/bin/foo.csh
set SCRIPT=`readlink -f "$0"`
# Absolute path this script is in, thus /home/user/bin
set SCRIPTPATH=`dirname "$SCRIPT"`
echo $SCRIPTPATH
Смотрите также: fooobar.com/questions/122/...
Ответ 3
Предполагая, что вы используете bash
#!/bin/bash
current_dir=$(pwd)
script_dir=$(dirname $0)
echo $current_dir
echo $script_dir
Этот script при запуске должен печатать каталог, в котором вы находитесь, а затем каталог script находится, например, при вызове его из /(script находится в /home/mez/ ), он выводит
/
/home/mez
Помните, что при назначении переменных из вывода команды завершите команду в $(и) - или вы не получите желаемый результат. `
Ответ 4
Если вы используете bash....
#!/bin/bash
pushd $(dirname "${0}") > /dev/null
basedir=$(pwd -L)
# Use "pwd -P" for the path without links. man bash for more info.
popd > /dev/null
echo "${basedir}"
Ответ 5
Более ранний комментарий к ответу сказал это, но его легко пропустить среди всех других ответов.
При использовании bash:
echo this file: $BASH_SOURCE
echo this dir: `dirname $BASH_SOURCE`
Ответ 6
Как говорит Марко:
BASEDIR=$(dirname $0)
echo $BASEDIR
Это работает, если вы не выполните script из того же каталога, где находится script, и в этом случае вы получите значение '.'
Чтобы обойти эту проблему, используйте:
current_dir=$(pwd)
script_dir=$(dirname $0)
if [ $script_dir = '.' ]
then
script_dir="$current_dir"
fi
Теперь вы можете использовать переменную current_dir на протяжении всего script, чтобы обратиться к каталогу script. Однако это может все еще иметь проблему с символикой.
Ответ 7
cd $(dirname $(readlink -f $0))
Ответ 8
Вдохновленный ответ blueyeds
read < <(readlink -f $0 | xargs dirname)
cd $REPLY
Ответ 9
Пусть это POSIX:
a="/$0"; a=${a%/*}; a=${a:-.}; a=${a#/}/; BASEDIR=$(cd $a; pwd)
Протестировано на многих совместимых с Bourne оболочках, включая BSD.
Насколько я знаю, я автор, и я помещаю его в общественное достояние. Для получения дополнительной информации см.: https://www.jasan.tk/posix/2017/05/11/posix_shell_dirname_replacement
Ответ 10
Лучший ответ на этот вопрос был дан здесь:
Получение исходного каталога Bash script изнутри
И есть:
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
Однострочный, который даст вам полное имя каталога script независимо от того, откуда он вызывается.
Чтобы понять, как это работает, вы можете выполнить следующее script:
#!/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" )" && pwd )"
if [ "$DIR" != "$RDIR" ]; then
echo "DIR '$RDIR' resolves to '$DIR'"
fi
echo "DIR is '$DIR'"
Ответ 11
Так много ответов, все правдоподобные, каждый из которых имеет pro и con и немного отличается от целей (что, вероятно, должно быть указано для каждого). Здесь другое решение, которое отвечает основной цели как прозрачности, так и работы во всех системах, на всех bash (без предположений о версиях bash или readlink
или pwd
), и разумно делает то, что вы (например, устранение символических ссылок - интересная проблема, но обычно это не то, что вы на самом деле хотите), обрабатывать крайние случаи, такие как пробелы в путях и т.д., игнорирует любые ошибки и использует разумные умолчания, если есть какие-либо проблемы.
Каждый компонент хранится в отдельной переменной, которую вы можете использовать индивидуально:
# script path, filename, directory
PROG_PATH=${BASH_SOURCE[0]} # this script name
PROG_NAME=${PROG_PATH##*/} # basename of script (strip path)
PROG_DIR="$(cd "$(dirname "${PROG_PATH:-$PWD}")" 2>/dev/null 1>&2 && pwd)"
Ответ 12
Это должно сделать трюк:
echo `pwd`/`dirname $0`
Он может выглядеть уродливым в зависимости от того, как он был вызван, и cwd, но должен получить вас туда, куда вам нужно идти (или вы можете настроить строку, если вам интересно, как она выглядит).