1

У меня есть два сценария. Один :

#!/bin/bash
if [ $1 = 1 ]; then 
   dir=mydir-1.6_
else
    dir=mydir
fi
cd ~/code/${dir}$2
echo $(pwd)

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

Теперь у меня есть другой скрипт:

#!/bin/bash
dir=/WORK/temp/$1
mkdir -p $dir
cd $dir
wget http://somurl.com/archive.zip
unzip archive.zip

Приведенный выше скрипт распаковывает файл в ожидаемую директорию, но оставляет вызывающую оболочку в той же директории. В чем разница, когда CD вызывается в обоих скриптах?

2 ответа2

0

Если я понимаю, в чем ваша проблема, вы можете попробовать выполнить второй скрипт из первого, передав его в ожидаемую директорию. Как это.

сценарий 1

#!/bin/bash
TEST="1234"
echo "$TEST"
bash 2.sh "$TEST"

сценарий 2

#!/bin/bash
TEST="$1"
echo "$TEST"
0

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

Единственный способ, которым он может изменить каталог родительской оболочки, - это если вы используете его вместо того, чтобы выполнять. Я сохранил ваш первый скрипт как foo.sh и запустил его из моего $HOME:

$ pwd
/home/terdon
$ foo.sh 1 
/home/terdon/code/mydir-1.6_
$ pwd
/home/terdon

Как видите, каталог изменяется внутри скрипта, но PWD родительской оболочки остается неизменным. Теперь, если вы найдете его, он работает так, как вы ожидаете:

$ . ~/scripts/foo.sh
bash: [: =: unary operator expected
/home/terdon/code/mydir
$ pwd
/home/terdon/code/mydir

Итак, если вы хотите, чтобы ваш скрипт изменил каталог своей родительской оболочки, вам нужно, чтобы исходный код не выполнял его. Однако, если вы пытаетесь это сделать, вы хотите написать функцию, а не скрипт:

changeDir(){
    targetDir="mydir"
    if [ "$1" = "1" ]; then
       targetDir="mydir-1.6_"
    fi
    \cd "$targetDir"
}

Добавьте вышеупомянутое в ваш ~/.bashrc и используйте его вместо скрипта. Функции всегда влияют на оболочку, которая их запускает, поэтому она изменит ваш каталог так, как вы этого хотите.

Обратите внимание, что я использую \cd вместо cd . Это в случае, если ваш cd связан с чем-то . Также обратите внимание, что я немного изменил ваш скрипт, чтобы избежать bash: [: =: unary operator expected вы получаете с вашим первоначальным подходом. В сценариях оболочки важно всегда заключать в кавычки ваши переменные. В этом случае, когда $1 был пуст, скрипт пытался запустить:

$ if [ = 1 ]; then  targetDir="mydir-1.6_"; fi
bash: [: =: unary operator expected

Что, конечно, выдает ошибку, поскольку сравнивать нечего. Цитируя $1 вы сравниваете пустую строку, и она будет работать как положено.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .