Почему "cd" не работает в сценарии оболочки?
Я пытаюсь написать небольшой script, чтобы изменить текущий каталог на мою директорию проекта:
#!/bin/bash
cd /home/tree/projects/java
Я сохранил этот файл как proj, добавил разрешение на выполнение с помощью chmod
и скопировал его в /usr/bin
. Когда я называю это:
proj
, он ничего не делает. Что я делаю неправильно?
Ответы
Ответ 1
Сценарии оболочки запускаются внутри подоболочки, и каждая подоболочка имеет свою собственную концепцию того, что представляет собой текущий каталог. cd
преуспевает, но как только подоболочка выйдет, вы вернетесь в интерактивную оболочку и там ничего не изменилось.
Один из способов обойти это - вместо этого использовать псевдоним:
alias proj="cd /home/tree/projects/java"
Ответ 2
Ты ничего не делаешь неправильно! Вы изменили каталог, но только внутри подоболочки, которая запускает script.
Вы можете запустить script в текущем процессе командой "dot":
. proj
Но я предпочел бы, чтобы Грег предложил использовать псевдоним в этом простом случае.
Ответ 3
cd
в script технически сработал, так как он изменил каталог оболочки, в которой запущен script, но это был отдельный процесс, разветвленный из вашей интерактивной оболочки.
Совместимый с Posix способ решить эту проблему - определить процедуру оболочки, а не команду, вызванную оболочкой script.
jhome () {
cd /home/tree/projects/java
}
Вы можете просто ввести это или поместить в один из различных файлов запуска оболочки.
Ответ 4
cd
выполняется в оболочке script. Когда конец script завершается, эта оболочка завершается, а затем вы остаетесь в каталоге, в котором вы были. "Источник" script, не запускайте его. Вместо:
./myscript.sh
делать
. ./myscript.sh
(Обратите внимание на точку и пробел перед именем script.)
Ответ 5
Чтобы сделать bash script, который будет cd в каталоге выбора:
Создайте файл script
#!/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 и вы там.
Ответ 6
Идея использования символической ссылки Джереми Рутен вызвала мысль, которая не перешла ни на один другой ответ. Использование:
CDPATH=:$HOME/projects
Ведущая толстая кишка важна; это означает, что если в текущем каталоге есть каталог 'dir', тогда 'cd dir
' изменится на это, вместо того, чтобы перепрыгивать куда-то еще. С установленным значением, как показано, вы можете сделать:
cd java
и если в текущем каталоге нет подкаталога java, он перенесет вас непосредственно в $HOME/projects/java - нет псевдонимов, нет скриптов, нет сомнительных exec или точечных команд.
My $HOME - это/Пользователи/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
Ответ 7
Вы можете использовать .
выполнить скрипт в текущей среде оболочки:
. script_name
или, альтернативно, его более читаемый, но специфичный для оболочки source
псевдонимов:
source script_name
Это позволяет избежать подоболочки и позволяет любым переменным или встроенным (включая cd
) вместо этого влиять на текущую оболочку.
Ответ 8
Я получил свой код для работы с помощью . <your file name>
./<your file name>
Доза не работает, потому что она не меняет ваш каталог в терминале, это просто изменяет каталог, специфичный для этого script.
Вот моя программа
#!/bin/bash
echo "Taking you to eclipse workspace."
cd /Developer/Java/workspace
Вот мой терминал
nova:~ Kael$
nova:~ Kael$ . workspace.sh
Taking you to eclipe workspace.
nova:workspace Kael$
Ответ 9
Используйте exec bash
в конце
Скрипт bash работает в текущей среде или в дочерних, но никогда в родительской среде.
Однако этот вопрос часто задают, потому что кто-то хочет остаться в (новом) приглашении bash в определенном каталоге после выполнения сценария bash из другого каталога.
Если это так, просто запустите дочерний экземпляр bash в конце скрипта:
#!/usr/bin/env bash
cd /home/tree/projects/java
exec bash
Ответ 10
просто запустите:
cd /home/xxx/yyy && command_you_want
Ответ 11
Когда вы запускаете оболочку script, она запускает новый экземпляр этой оболочки (/bin/bash
). Таким образом, ваш script просто запускает оболочку, меняет каталог и завершает работу. Другими словами, cd
(и другие такие команды) внутри оболочки script не влияют и не имеют доступа к оболочке, из которой они были запущены.
Ответ 12
Вы можете выполнить следующие действия:
#!/bin/bash
cd /your/project/directory
# start another shell and replacing the current
exec /bin/bash
EDIT: это также может быть "пунктиром", чтобы предотвратить создание последующих оболочек.
Пример:
. ./previous_script (with or without the first line)
Ответ 13
В моем конкретном случае мне понадобилось слишком много раз, чтобы изменить для одного и того же каталога.
Так что на моем .bashrc(я использую ubuntu) я добавил
1 -
$nano ~./bashrc
function switchp
{
cd /home/tree/projects/$1
}
2-
$source ~/.bashrc
3 -
$switchp java
Непосредственно это будет делать: cd/home/tree/projects/java
Надеюсь, что это поможет!
Ответ 14
Он меняет только каталог для самого script, тогда как текущий каталог остается прежним.
Вместо этого вы можете использовать символическую ссылку . Это позволяет вам создать "ярлык" для файла или каталога, поэтому вам нужно будет только что-то напечатать как cd my-project
.
Ответ 15
Вы можете комбинировать псевдоним и script,
alias proj="cd \`/usr/bin/proj !*\`"
при условии, что script echos путь назначения. Обратите внимание, что это backticks, окружающие имя script.
Например, ваш script может быть
#!/bin/bash
echo /home/askgelal/projects/java/$1
Преимущество этой методики состоит в том, что script может принимать любое количество параметров командной строки и испускать разные адресаты, рассчитанные, возможно, сложной логикой.
Ответ 16
быстро перемещаться по каталогам, есть CDPATH, cdargs и способы генерации псевдонимов автоматически
http://jackndempsey.blogspot.com/2008/07/cdargs.html
http://muness.blogspot.com/2008/06/lazy-bash-cd-aliaes.html
https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-5827311.html
Ответ 17
Вы можете комбинировать псевдонимы Адама и Грега и точки, чтобы сделать что-то более динамичное -
alias project=". project"
Теперь запущенный псевдоним проекта выполнит проект script в текущей оболочке, а не в подоболочке.
Ответ 18
Вы можете использовать оператор &&
cd myDirectory && Ls
Ответ 19
В файле ~/.bash_profile. добавьте следующую функцию
move_me() {
cd ~/path/to/dest
}
Перезагрузите терминал, и вы можете ввести
move_me
и вы будете перемещены в папку назначения.
Ответ 20
В то время как поиск script, который вы хотите запустить, является одним из решений, вы должны знать, что этот script затем может напрямую изменить среду вашей текущей оболочки. Также невозможно передать аргументы.
Другой способ сделать это - реализовать script как функцию в bash.
function cdbm() {
cd whereever_you_want_to_go
echo "Arguments to the functions were $1, $2, ..."
}
Этот метод используется autojump: http://github.com/joelthelion/autojump/wiki, чтобы предоставить вам учебные закладки в каталоге оболочки.
Ответ 21
Это должно делать то, что вы хотите. Перейдите в каталог, представляющий интерес (из скрипта), а затем создайте новую оболочку bash.
#!/bin/bash
# saved as mov_dir.sh
cd ~/mt/v3/rt_linux-rt-tools/
bash
Если вы запустите это, то вы попадете в интересующий каталог, а когда вы выйдете из него, вы вернетесь в исходное место.
[email protected]:~# ./mov_dir.sh
[email protected]:~/mt/v3/rt_linux-rt-tools# exit
[email protected]:~#
Это даже приведет вас к исходному каталогу при выходе (CTRL + d)
Ответ 22
LOOOOOng после этого, но я сделал следующее:
создать файл с именем case
вставьте в файл следующее:
#!/bin/sh
cd /home/"$1"
сохраните его, а затем:
chmod +x case
Я также создал псевдоним в своем .bashrc
:
alias disk='cd /home/; . case'
теперь, когда я печатаю:
case 12345
по существу я печатаю:
cd /home/12345
Вы можете ввести любую папку после "case":
case 12
case 15
case 17
который похож на ввод:
cd /home/12
cd /home/15
cd /home/17
соответственно
В моем случае путь намного длиннее - эти ребята суммировали его с информацией раньше.
Ответ 23
Вы можете создать функцию, как .bash_profile
ниже, в вашем .bash_profile
и она будет работать гладко.
Следующая функция принимает необязательный параметр, который является проектом. Например, вы можете просто запустить
cdproj
или же
cdproj project_name
Вот определение функции.
cdproj(){
dir=/Users/yourname/projects
if [ "$1" ]; then
cd "${dir}/${1}"
else
cd "${dir}"
fi
}
Не забудьте .bash_profile
свой .bash_profile
Ответ 24
Вот сообщение в блоге, которое я написал о конкретной проблеме:
http://blog.sampsonchen.com/2012/09/18/three-shortcuts-to-quickly-change-directories-in-linux/
Также есть инструмент для этого: z: https://github.com/rupa/z
Ответ 25
Если вы используете fish в качестве оболочки, лучшим решением является создание функции. В качестве примера, учитывая исходный вопрос, вы можете скопировать 4 строки ниже и вставить их в свою командную строку для рыб:
function proj
cd /home/tree/projects/java
end
funcsave proj
Это создаст функцию и сохранит ее для использования позже. Если ваш проект меняется, просто повторите процесс, используя новый путь.
Если вы предпочитаете, вы можете вручную добавить файл функции, выполнив следующие действия:
nano ~/.config/fish/functions/proj.fish
и введите текст:
function proj
cd /home/tree/projects/java
end
и, наконец, нажмите ctrl + x для выхода и y, а затем верните, чтобы сохранить изменения.
(ПРИМЕЧАНИЕ: первый способ использования funcsave создает для вас файл proj.fish).
Ответ 26
У меня есть простой bash script p для управления изменением каталога на github.com/godzilla/bash-stuff
просто поместите script в свой локальный каталог bin (/usr/local/bin)
и положите
alias p='. p'
в вашем .bashrc
Ответ 27
Вам не нужно script, установите только правильный параметр и создайте переменную окружения.
shopt -s cdable_vars
в вашем ~/.bashrc
позволяет cd
содержать содержимое переменных среды.
Создайте такую переменную среды:
export myjava="/home/tree/projects/java"
и вы можете использовать:
cd myjava
Другие альтернативы.
Ответ 28
Использование функций профиля Bash:
Одной из особенностей профиля bash является хранение пользовательских функций, которые можно запускать в терминале или в сценариях bash, так же, как вы запускаете приложение/команды, это также можно использовать в качестве ярлыка для длинных команд.
Чтобы ваша система работала эффективно, вам нужно будет скопировать свою функцию в конце нескольких файлов.
/home/user/.bashrc
/home/user/.bash_profile
/root/.bashrc
/root/.bash_profile
Вы можете sudo kwrite/home/user/.bashrc/home/user/.bash_profile/root/.bashrc/root/.bash_profile
для sudo kwrite/home/user/.bashrc/home/user/.bash_profile/root/.bashrc/root/.bash_profile
редактирования/создания этих файлов
Пример скрипта
Создание ярлыка на cd..
с cdd
cdd() {
cd ..
}
лс ярлык
ll() {
ls -l -h
}
лс ярлык
lll() {
ls -l -h -a
}
Как :
Скопируйте свою функцию в конце ваших файлов и перезагрузите терминал, после чего вы можете запустить cdd
или любую cdd
функцию, которую вы написали.
Ответ 29
Обратите внимание на обсуждение. Как мне установить рабочий каталог родительского процесса?
Он содержит некоторые хакерские ответы, например fooobar.com/questions/133653/... (изменение каталога родительского процесса с помощью GDB, не делайте этого) и fooobar.com/questions/133653/... ( команда tailcd
которая внедряет имя tailcd
диска во входной поток родительского процесса; в идеале это должна быть часть bash, а не хак)
Ответ 30
Вы можете выполнить некоторые строки в одной и той же подоболочке, если вы закончите строки с обратной косой чертой.
cd somedir; \
pwd