Почему «cd» не работает в сценарии оболочки? - PullRequest
685 голосов
/ 01 ноября 2008

Я пытаюсь написать небольшой скрипт, чтобы изменить текущий каталог на каталог моего проекта:

#!/bin/bash
cd /home/tree/projects/java

Я сохранил этот файл как proj, добавил разрешение на выполнение с chmod и скопировал его в /usr/bin. Когда я звоню по: proj, это ничего не делает. Что я делаю не так?

Ответы [ 29 ]

583 голосов
/ 01 ноября 2008

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

Один из способов обойти это - использовать вместо этого псевдоним:

alias proj="cd /home/tree/projects/java"
460 голосов
/ 01 ноября 2008

Вы не делаете ничего плохого! Вы изменили каталог, но только внутри подоболочки, которая запускает сценарий.

Вы можете запустить скрипт в текущем процессе с помощью команды "точка":

. proj

Но я бы предпочел, чтобы Грег предложил использовать псевдоним в этом простом случае.

208 голосов
/ 11 августа 2011

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

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

jhome () {
  cd /home/tree/projects/java
}

Вы можете просто набрать это или поместить в один из различных файлов запуска оболочки.

140 голосов
/ 10 февраля 2010

cd выполняется внутри оболочки скрипта. Когда сценарий заканчивается, оболочка завершается, и вы остаетесь в том каталоге, в котором находились «Исходный» сценарий, не запускайте его. Вместо:

./myscript.sh

сделать

. ./myscript.sh

(Обратите внимание на точку и пробел перед именем скрипта.)

90 голосов
/ 06 мая 2010

Чтобы создать bash-скрипт, который перейдет в выбранный каталог:

Создать файл скрипта

#!/bin/sh
# file : /scripts/cdjava
#
cd /home/askgelal/projects/java

Затем создайте псевдоним в вашем файле запуска.

#!/bin/sh
# file /scripts/mastercode.sh
#
alias cdjava='. /scripts/cdjava'

  • Я создал файл запуска, в который я выгружаю все свои псевдонимы и пользовательские функции.
  • Затем я отправляю этот файл в мой .bashrc, чтобы он устанавливался при каждой загрузке.

Например, создайте основной файл псевдонимов / функций: / scripts / mastercode.sh
(укажите псевдоним в этом файле.)

Затем в конце вашего .bashrc файла:

source /scripts/mastercode.sh



Теперь легко перейти в ваш каталог java, просто наберите cdjava, и вы уже там.

36 голосов
/ 01 ноября 2008

Идея Джереми Рутена об использовании символической ссылки вызвала мысль, которая не нашла никакого другого ответа. Использование:

CDPATH=:$HOME/projects

Важна ведущая толстая кишка; это означает, что если в текущем каталоге есть каталог 'dir', то 'cd dir' изменится на этот, а не будет прыгать куда-то еще. С установленным значением, как показано, вы можете сделать:

cd java

и, если в текущем каталоге нет подкаталога с именем java, он приведет вас прямо к $ HOME / projects / java - без псевдонимов, без скриптов, без сомнительных команд execs или dot.

Мой $ HOME - это / Users / jleffler; мой $ CDPATH:

:/Users/jleffler:/Users/jleffler/mail:/Users/jleffler/src:/Users/jleffler/src/perl:/Users/jleffler/src/sqltools:/Users/jleffler/lib:/Users/jleffler/doc:/Users/jleffler/work
36 голосов
/ 10 февраля 2014

Вы можете использовать . для выполнения скрипта в текущей среде оболочки:

. script_name

или, альтернативно, его более читаемый, но специфичный для оболочки псевдоним source:

source script_name

Это позволяет избежать подоболочки и позволяет любым переменным или встроенным функциям (включая cd) вместо этого влиять на текущую оболочку.

25 голосов
/ 28 октября 2012

Я получил свой код для работы с помощью . <your file name>

./<your file name> доза не работает, потому что она не меняет ваш каталог в терминале, она просто меняет каталог, специфичный для этого скрипта.

Вот моя программа

#!/bin/bash 
echo "Taking you to eclipse's workspace."
cd /Developer/Java/workspace

Вот мой терминал

nova:~ Kael$ 
nova:~ Kael$ . workspace.sh
Taking you to eclipe's workspace.
nova:workspace Kael$ 
21 голосов
/ 21 апреля 2016

Используйте exec bash в конце

Сценарий bash работает в своей текущей среде или в своей среде. дети, но никогда не в родительской среде.

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

Если это так, просто выполните дочерний экземпляр bash в конце сценария:

#!/usr/bin/env bash
cd /home/tree/projects/java
exec bash
17 голосов
/ 10 марта 2017

просто запустите:

cd /home/xxx/yyy && command_you_want
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...