BASH скрипт для установки переменных окружения не работает

137

Я написал следующий скрипт для установки некоторых переменных среды, когда это необходимо.

#!/bin/sh
export BASE=/home/develop/trees
echo $BASE
export PATH=$PATH:$BASE
echo $PATH

Ниже команды и результаты, которые я вижу на своем терминале: скрипт выполняется, но переменные не устанавливаются в конце.

~$: ./script.sh
/home/develop/trees
/bin:......:/home/develop/trees
~$: echo $BASE

~$: 

В чем дело? Заранее спасибо. Mirko

MirkoZa
источник

Ответы:

194

exportэкспортирует присвоение переменной дочерним процессам оболочки, в которой была выполнена exportкоманда. Ваша среда командной строки является родителем оболочки скрипта, поэтому она не видит присваивание переменной.

Вы можете использовать команду .(или source) bash для выполнения команд сценария в текущей среде оболочки и достижения желаемого, например,

source ./script.sh
echo "$BASE"

Будет производить

/home/develop/trees

Команда source, часто встречающаяся в скриптах, является синонимом bash ., который является частью стандарта POSIX ( .например, доступен в dash, но sourceне доступен ).

. ./script.sh     # identical to "source ./script.sh"

( . script.shи source script.shсначала будет искать script.shв PATH, так что безопаснее указать путь к script.sh.)

Мур
источник
29
Вам не нужно exportпередавать переменные в подоболочки, подоболочка - это копия вашей текущей оболочки, включая переменные и функции и т. Д. Экспортированные переменные копируются в новые процессы, порожденные из оболочки, независимо от того, является ли этот процесс другой оболочкой или нет. Во-вторых, .это команда POSIX для поиска. Bash добавляет его sourceкак более читаемый синоним, но вы не можете полагаться на то, что он доступен в sh. Наконец, . ./scriptвместо того . script, чтобы избежать неожиданностей. mywiki.wooledge.org/BashFAQ/060
гейра
Обратите внимание, что если вы создаете сценарий И используете pipe, тогда исходная среда недоступна для родительского элемента. например, 'source setit.sh' в порядке. 'source setit.sh | tee setit.log' не в порядке. Удивительный. Не интуитивно понятно
gaoithe
10

Когда вы запускаете скрипт, он запускается в подоболочке. Переменные действительны только в контексте этой подоболочки. Установите их в вашем .bashrcили .profileи читайте о переменных и подоболочках . Это exportутверждение работает вниз по иерархии (текущая оболочка и все ее подоболочки), а не как в вашем примере.

В качестве альтернативы (если вы действительно хотите, чтобы скрипт воздействовал на окружающую среду вашей текущей оболочки), запустите его следующим образом:

. ./script.sh

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

кон-е использование
источник
5

Я часто хочу установить переменную среды без хлопот.

Вот что я добавляю в мой .bashrc для реализации этого удобства.

defect() {
    if [ $1 ] && [ -z $2 ]
    then
        eval 'export DEFECT=$1'
        return 0
    else
        echo 'Usage: defect {number}'
        return 1
    fi
}
jlettvin
источник
-1

Вы можете попробовать что-то вроде этого

CURRENT_DIR=`pwd`
echo "SOME_PATH is pointing to ${CURRENT_DIR}"
#Export SOME_PATH for current working directory
export SOME_PATH=${CURRENT_DIR}
silentsudo
источник