Почему я не могу изменить каталоги, используя "cd" в скрипте?

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

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

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

межсайтовый дубликат: superuser.com/questions/176783/…

lesmana 26.07.2014 23:48

В дальнейшем вы всегда можете попробовать протестировать его с помощью pwd в последней строке. Итак, перед завершением скрипта вы можете проверить, работает он или нет ..

sobi3ch 30.09.2015 23:22

@lesmana, как это дубликат?

aland 09.01.2016 01:43

@aland Поскольку OP действительно запускает сценарий нет, рабочий каталог для него не меняется. Команда cd хорошо работает внутри скриптов, попробуйте сами.

Alexander Gonchiy 10.11.2016 16:41
xdotool type --clearmodifiers 'cd ~/projects/java' && xdotool key KP_Enter
Vyacheslav Konovalov 29.07.2019 16:50

По сути это дубликат stackoverflow.com/questions/1464253/…

tripleee 22.03.2021 10:08
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
789
7
659 749
32
Перейти к ответу Данный вопрос помечен как решенный

Ответы 32

Ответ принят как подходящий

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

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

alias proj = "cd /home/tree/projects/java"

Псевдонимы не так гибки для управления или изменения. В случае большого количества компакт-дисков сценарии могут быть лучше.

Thevs 01.11.2008 07:30

Функции более гибкие, чем псевдонимы, поэтому, когда псевдонимов недостаточно, вам следует искать дальше.

ephemient 01.11.2008 07:40

Я думаю, что это обсуждение теряет смысл. «Есть миллионы способов делать что-то на Perl» (tm)

Thevs 01.11.2008 07:54

+1 за отличное объяснение вкупе с полезной альтернативой!

Adam Liss 01.11.2008 21:25

Стоит ли отмечать, что в MS-DOS поведение сценариев было таким, что вызываемый сценарий мог изменить каталог (и даже диск) вызывающей командной оболочки? А что в Unix этого дефекта нет?

Jonathan Leffler 05.11.2008 02:08

Джонатан: хотя это правда, на самом деле это не связано с вопросом. Ответы на SO были бы вдвое длиннее, если бы каждый из них перечислял соответствующие недостатки MS-DOS!

Greg Hewgill 05.11.2008 02:52

s / дефект / побочный эффект /; s / стоит отметить / not & /

michael 17.10.2014 19:35

@ FedericoA.Ramponi или в ~ / .bash_aliases

Alex Vauch 11.03.2015 15:18

Другой способ обойти это - загрузить файл сценария: . my-script или source my-script.

HelloGoodbye 17.06.2015 23:38

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

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

. proj

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

. также пишется как source, выберите тот, который вам больше запомнился.
ephemient 01.11.2008 07:41

@Ephemient: Хороший источник очков. Это объясняет, почему это рабочий источник. Также доказывает, что лень, а не необходимость, часто является источником изобретения.

Adam Liss 01.11.2008 21:24

@ephemient: обратите внимание, что исходный код используется в оболочке C и Bash; он не поддерживается ни в POSIX, ни в оболочках Korn, ни в классической оболочке Bourne.

Jonathan Leffler 24.11.2008 07:40

"источник" используется в Z-оболочке

Nathan Moos 15.05.2013 02:52

@AdamLiss Отлично работает, но есть один недостаток - каким-то образом команда source / dot отключает возможность автозавершения имени скрипта / команды клавишей TAB. По-прежнему можно добавлять аргументы / ввод с помощью клавиши TAB, но, к сожалению, имя команды необходимо вводить напрямую. Вы знаете, как заставить работать клавишу TAB в этом случае?

Rafal 23.01.2014 12:08

@Rafal Я тестировал это в своей системе (с терминала PuTTY). Я смог заполнить имя команды табуляцией без проблем как для точки, так и для «источника». Может быть, ваше окружение?

Stuart 04.02.2015 21:16

@ Стюарт. Ты прав. Я только что протестировал это на Ubuntu 14.04, и завершение табуляции отлично работает. Вероятно, это была проблема с Ubuntu 13.10 еще в январе 2014 года или, может быть, с моей конфигурацией. Спасибо за информацию.

Rafal 19.02.2015 17:33

Когда вы запускаете сценарий оболочки, он запускает экземпляр новый этой оболочки (/bin/bash). Таким образом, ваш скрипт просто запускает оболочку, меняет каталог и завершает работу. Другими словами, cd (и другие подобные команды) в сценарии оболочки не влияют и не имеют доступа к оболочке, из которой они были запущены.

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

Вместо этого вы можете использовать символическая ссылка. Он позволяет вам создать «ярлык» для файла или каталога, поэтому вам нужно будет только ввести что-то вроде cd my-project.

Наличие этой символической ссылки в каждом каталоге было бы неприятностью. Можно было бы поместить символическую ссылку в $ HOME, а затем выполнить cd ~ / my-project. Честно говоря, CDPATH проще использовать.

Jonathan Leffler 01.11.2008 08:56

Вы можете сделать следующее:

#!/bin/bash
cd /your/project/directory
# start another shell and replacing the current
exec /bin/bash

Обновлено: это также может быть «пунктирным», чтобы предотвратить создание последующих оболочек.

Пример:

. ./previous_script  (with or without the first line)

Это становится довольно беспорядочным после нескольких запусков .. Вам придется несколько раз нажать exit (или ctrl + d), чтобы выйти, например, из оболочки. Псевдоним намного чище (даже если команда оболочки выводит каталог, и он cd к выходу - alias something = "cd getnewdirectory.sh")

dbr 01.11.2008 06:15

Обратите внимание на «exec». Заменяет старую оболочку.

Thevs 01.11.2008 07:06

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

Jonathan Leffler 01.11.2008 07:15

Сделайте это «пунктирным» - без проблем. Я только что предложил решение. Это не зависит от того, как вы это запустите.

Thevs 01.11.2008 07:22

Хе-хе, я думаю, что лучше просто расставить однострочный скрипт точкой с помощью одной команды cd :) Я все равно сохраню свой ответ ... Это будет правильный глупый ответ на неправильный глупый вопрос :)

Thevs 01.11.2008 08:01
stackoverflow.com/questions/874452/… - это то, что я предлагаю для интерактивного использования для запуска среды разработки.
philippe lhardy 02.03.2013 00:04

exec / bin / bash сделал то, что мне нужно. Спасибо!

Sergio Abreu 06.05.2018 16:38

Это помогло мне решить нерешенную проблему loong. Большое спасибо.

Darshan L 21.11.2020 15:12

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

CDPATH=:$HOME/projects

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

cd java

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

Мой $ 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

для быстрой навигации по каталогам есть $ 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

Вы можете комбинировать псевдоним и скрипт,

alias proj = "cd \`/usr/bin/proj !*\`"

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

Например, ваш сценарий может быть

#!/bin/bash
echo /home/askgelal/projects/java/$1

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

Почему? вы можете просто использовать: proj() { cd "/home/user/projects/java/$1"; } => proj "foo" (или, proj "foo bar" <=, если у вас есть пробелы) ... или даже (например): proj() { cd "/home/user/projects/java/$1"; shift; for d; do cd "$d"; done; } => proj a b c => делает cd в /home/user/projects/java/a/b/c

michael 17.10.2014 19:52

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

./myscript.sh

делать

. ./myscript.sh

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

Это круто и, наверное, полезно знать. Но что именно последний делает (как это работает)? Это, наверное, лучшее решение в этой теме.

Jonah 14.03.2012 00:40

fwiw, в разделе комментариев к ответу Адама Лисса ephemient отвечает на вопрос о том, что это за '.' является. Это то же самое, что и source

g19fanatic 27.11.2012 22:38

Будьте осторожны, «источник» - это башизм. т.е. тире (Debian по умолчанию для / bin / sh) не поддерживает его, а "." работает как положено.

allo 05.10.2017 12:00

Отличный ответ! также, если myscript.sh находится в каталоге, включенном в $ PATH, вы можете получить его откуда угодно, не указывая полный путь.

CodeBrew 07.02.2019 01:10

Это сработало для меня лучше всего. Это самое простое решение (+1).

HuserB1989 05.05.2020 23:56

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

Создайте файл сценария

#!/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



Теперь легко перейти к cd в ваш каталог java, просто введите cdjava, и вы там.

файл mastercode.sh не нуждается в шабанге (#!/bin/sh), поскольку он не (и не может быть) выполнен в подоболочке. Но в то же время вам необходимо задокументировать "вкус" оболочки этого файла; например, ksh или bash (или (t) csh / zsh и т. д.), и почти наверняка это не sh. Я обычно добавляю комментарий (но не шебанг), чтобы сообщить об этом; например, «этот файл должен быть получен (из bash), а не запускаться как сценарий оболочки».

michael 17.10.2014 19:44

Еще один совет (для bash): если вы используете переменные в своем скрипте, то, поскольку скрипт является sourced (через alias), эти переменные попадут в среду вашей оболочки. Чтобы этого избежать, выполняйте всю работу сценария в функции и просто вызывайте ее в конце сценария. Внутри функции объявите любые переменные local.

Rhubbarb 17.04.2015 18:55

в ubuntu просто создайте ~ / .bash_aliases (если он еще не существует). Затем просто добавьте туда свои псевдонимы, перезапустите терминал и готово.

Vlad 02.06.2016 10:56

Я сделал следующее:

создать файл с именем 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

соответственно

В моем случае путь намного длиннее - эти ребята резюмировали его с помощью информации ~ ранее.

cd в псевдониме лишний и неэлегантный; псевдоним должен просто '. ~ / case` вместо этого. Кроме того, case - это зарезервированное ключевое слово, поэтому это довольно плохой выбор для имени.

tripleee 29.07.2015 21:24

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

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

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

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

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

Justin Buser 26.03.2013 09:31

Это похоже на решение! И я пытаюсь реализовать его, но он не работает :( вот мой сценарий: #! / Bin / bash jhome () {echo "please" cd / home echo "work"} jhome

Gant Laborde 17.02.2014 20:10

@GantMan, вы должны добавить это в "файлы запуска оболочки", например ~ / .bashrc

Jackie Yeh 03.12.2014 05:57

Если он находится в файле, вам нужно использовать . filename или source filename, чтобы текущая оболочка увидела его, а не подоболочку, которая выполнила команду. Или воспользуйтесь советом Джеки и вставьте что-нибудь вроде ~/.bashrc.

DigitalRoss 25.03.2015 21:28

Вы также можете использовать аргумент (или два ...), например: jhome(){ cd /home/tree/projects/$1; }

irbanana 12.02.2016 20:48

Это должно быть правильным способом, это позволяет использовать специальные символы, такие как, например, «-».

bangkokguy 27.04.2016 20:46

Отлично, просто решил мою проблему безупречно. При этом следует отметить правильный ответ.

Pedro Sousa 06.06.2016 17:12

Вы можете комбинировать псевдонимы Адама и Грега и точечный подход, чтобы сделать что-то более динамичное -

alias project = ". project"

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

Это именно то, что мне нужно, чтобы поддерживать весь мой скрипт и просто вызывать его из bash и поддерживать текущий сеанс - это ИДЕАЛЬНЫЙ ответ.

Matt The Ninja 18.09.2019 16:55

В моем конкретном случае мне нужно было слишком много раз менять один и тот же каталог. Итак, на моем .bashrc (я использую ubuntu) я добавил

1 -

$ nano ~./bashrc

 function switchp
 {
    cd /home/tree/projects/$1
 }

2-

$ source ~/.bashrc

3 -

$ switchp java

Непосредственно это будет: cd / home / tree / projects / java

Надеюсь, это поможет!

@ W.M. В конечном итоге вы можете выполнить команду «$ switchp» без каких-либо параметров, чтобы перейти непосредственно к дереву проекта.

workdreamer 06.07.2016 12:46

@workdreamer Функциональный подход, который вы описали выше, решил небольшую проблему при переходе в подпапки, которые имеют ту же родительскую папку в моей системе. Спасибо.

W.M. 06.07.2016 13:11

Я заставил свой код работать с помощью . <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$ 

В чем разница между . something и ./something ?? Этот ответ сработал для меня, и я не понимаю, почему.

Dracorat 03.11.2012 00:34
. something позволяет запускать сценарий из любого места, ./something требует, чтобы вы находились в каталоге, в котором хранится файл.
Projjol 13.07.2014 17:20

@Dracorat stackoverflow.com/questions/13786499/…

tripleee 03.04.2016 08:52

Вы можете поставить точку в строке shebang? #!. /bin/bash?

Sigfried 19.04.2020 21:32

Если вы используете рыбы в качестве оболочки, лучшим решением будет создание функции. В качестве примера, учитывая исходный вопрос, вы можете скопировать 4 строки ниже и вставить их в командную строку fish:

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, а затем return, чтобы сохранить изменения.

(ПРИМЕЧАНИЕ: первый метод использования funcsave создает для вас файл proj.fish.).

Вы можете использовать оператор &&:

cd myDirectory && ls

Голос против: это не попытка ответить на актуальный вопрос здесь. Вы можете запустить две команды в командной строке (с &&, если вы хотите, чтобы вторая была условной для первой, или просто с ; или новой строкой между ними), но вставка этого в сценарий вернет вас к вопросу «почему не родительский оболочки использовать новый каталог, когда cd действительно был успешным? "

tripleee 12.08.2016 08:21

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

cd somedir; \
pwd

В вашем файле ~ / .bash_profile. добавить следующую функцию

move_me() {
    cd ~/path/to/dest
}

Перезагрузите терминал, и вы можете ввести

move_me 

и вы будете перемещены в папку назначения.

У меня есть простой сценарий bash под названием p для управления изменением каталога на
github.com/godzilla/bash-stuff
просто поместите скрипт в локальный каталог bin (/ usr / local / bin)
и ставим

alias p='. p'

в вашем .bashrc

что это делает? похоже, что он будет рекурсивно запускаться сам, хотя я уверен, что если вы запускали его раньше, он этого не сделает;)

Ryan Taylor 15.03.2019 21:03

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

Другой способ - реализовать ваш скрипт как функцию в bash.

function cdbm() {
  cd whereever_you_want_to_go
  echo "Arguments to the functions were $1, $2, ..."
}

Этот метод используется функцией autojump: http://github.com/joelthelion/autojump/wiki, чтобы предоставить вам обучающие закладки каталога оболочки.

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

. script_name

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

source script_name

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

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

A bash script operates on its current environment or on that of its children, but never on its parent environment.

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

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

#!/usr/bin/env bash
cd /home/tree/projects/java
echo -e '\nHit [Ctrl]+[D] to exit this child shell.'
exec bash

Чтобы вернуться к предыдущему родительскому экземпляру bash, используйте Ctrl + D.

Обновлять

По крайней мере, с более новыми версиями bash, exec в последней строке больше не требуется. Более того, сценарий можно заставить работать с любой предпочтительной оболочкой, используя переменную среды $SHELL. Тогда это дает:

#!/usr/bin/env bash
cd desired/directory
echo -e '\nHit [Ctrl]+[D] to exit this child shell.'
$SHELL

Это создает новую подоболочку. Когда вы наберете exit, вы вернетесь в оболочку, в которой вы запускали этот скрипт.

tripleee 12.08.2016 08:17

Когда скрипт вызывается несколько раз, кажется, что он создает вложенные оболочки, и мне нужно много раз вводить «выход». Можно ли это как-то решить?

VladSavitsky 19.10.2019 11:32

См. Другие ответы: используйте псевдоним, используйте "pushd / popd / dirs" или используйте "source"

qneill 04.02.2020 02:10

@Acumenus Вы совершенно правы. exec требовался со старыми версиями bash и, возможно, другими оболочками. Я обновил ответ соответственно.

Serge Stroobandt 25.10.2020 13:50

Могу ли я после запуска exec bash оставаться в сценарии и продолжать выполнять другие команды?

alper 09.03.2021 16:35

@alper Да, конечно. В новом дочернем экземпляре bash можно выполнить больше команд. Чтобы вернуться к предыдущему родительскому экземпляру bash, используйте [Ctrl] + [D].

Serge Stroobandt 11.03.2021 04:10

Вы можете создать в вашем .bash_profile функцию, как показано ниже, и она будет работать без сбоев.

Следующая функция принимает необязательный параметр - проект. Например, вы можете просто запустить

cdproj

или же

cdproj project_name

Вот определение функции.

cdproj(){
    dir=/Users/yourname/projects
    if [ "$1" ]; then
      cd "${dir}/${1}"
    else
      cd "${dir}"
    fi
}

Не забудьте указать источник вашего .bash_profile

Вам не нужен скрипт, только установите правильный параметр и создайте переменную среды.

shopt -s cdable_vars

в вашем ~/.bashrc позволяет cd содержимое переменных среды.

Создайте такую ​​переменную окружения:

export myjava = "/home/tree/projects/java"

и вы можете использовать:

cd myjava

Другие альтернативы.

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

cd /home/xxx/yyy && command_you_want

Как объяснялось в других ответах, вы изменили каталог, но только в суб-оболочка, которая запускает скрипт. это не влияет на родительскую оболочку.

Одно из решений - использовать функции bash вместо сценария bash (sh); поместив код сценария bash в функцию. Это делает функцию доступной как команду, а затем она будет выполняться без дочернего процесса, и, таким образом, любая команда cd повлияет на оболочку вызывающего.

Функции 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 для быстрого редактирования / создания этих файлов

Как :

Скопируйте код сценария bash в новую функцию в конце файла профиля bash и перезапустите терминал, затем вы можете запустить cdd или любую другую функцию, которую вы написали.

Пример сценария

Делаем ярлык на cd .. с cdd

cdd() {
  cd ..
}

ls ярлык

ll() {
  ls -l -h
}

ls ярлык

lll() {
  ls -l -h -a
}

Это действительно работает. Я удивлен, что за него не проголосовали так, как он того заслуживает.

Eerik Sven Puudist 07.08.2020 19:54

@EerikSvenPuudist :) это был поздний ответ на популярный пост, я думаю, читатели не дойдут до него, спасибо за голос

intika 07.08.2020 19:58

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

#!/bin/bash

# saved as mov_dir.sh
cd ~/mt/v3/rt_linux-rt-tools/
bash

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

root@intel-corei7-64:~# ./mov_dir.sh

root@intel-corei7-64:~/mt/v3/rt_linux-rt-tools# exit
root@intel-corei7-64:~#

Это даже вернет вас обратно в исходный каталог при выходе (CTRL + d)

Создание нового bash будет означать, что вы потеряете свою историю, и она начнется заново.

Tisch 30.05.2018 13:56

Обратите внимание на обсуждение Как установить рабочий каталог родительского процесса?

Он содержит несколько хакерских ответов, например https://stackoverflow.com/a/2375174/755804 (изменение каталога родительского процесса через gdb, не делайте этого) и https://stackoverflow.com/a/51985735/755804 (команда tailcd, которая вводит cd dirname во входной поток родительского процесса; в идеале она должна быть частью bash, а не взломом)

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

Вместо использования компакт диск вы можете использовать

export PWD=the/path/you/want

Нет необходимости создавать подоболочки или использовать псевдонимы.

Обратите внимание, что вы обязаны убедиться, что / path / you / want существует.

Мне нужно работать в tcsh, и я знаю, что это не изящное решение, но, например, если бы мне пришлось изменить папки на путь, в котором одно слово отличается, все это можно сделать в псевдониме

a alias_name 'set a = `pwd`; set b = `echo $a | replace "Trees" "Tests"` ; cd $b'

Если путь всегда фиксирован, справедливо

a alias_name2 'cd path/you/always/need'

должно сработать В строке выше установлен новый путь к папке

Это объединяет ответ Сергея с несвязанный ответ Дэвида. Он меняет каталог, а затем вместо принудительной установки оболочки bash использует запускает оболочку пользователя по умолчанию. Однако для определения оболочки по умолчанию требуются как getent, так и /etc/passwd.

#!/usr/bin/env bash
cd desired/directory
USER_SHELL=$(getent passwd <USER> | cut -d : -f 7)
$USER_SHELL

Конечно, это все тот же недостаток создания вложенной оболочки.

Другие вопросы по теме