Сценарій для зміни поточного каталогу (cd, pwd)


44

Я хочу запустити сценарій, щоб просто змінити поточний робочий каталог:

#!/bin/bash
cd web/www/project

Але після запуску його поточний pwd залишається незмінним! Як я можу це зробити?

Відповіді:


63

Це очікувана поведінка, про яку вже йшлося кілька разів.

Сценарій запускається в допоміжній оболонці і не може змінити робочий каталог батьківської оболонки. Його ефекти втрачаються, коли він закінчується.

Щоб назавжди змінити каталог, ви повинні джерело сценарію, як у

. ./script

8
@Sony: Зауважте, що вам слід скористатися returnдля виходу зі скрипту, який отримується таким чином, а не exit- вони схожі на функції оболонки, і вони exitвийдуть з оболонки, яка створювала сценарій.
Чарльз Стюарт

@CharlesStewart Насправді я не знайомий зі скриптами, що розміщуються. Дякую!
Sony Santos

5
це source ./scriptте саме?
amyassin

2
@amyassin: так, це
enzotib

2
1. .і sourceрівні в басі. 2. нам не потрібно використовувати ./перед назвою файлу, якщо він знаходиться в одному каталозі. Добре бігати тільки так:. script
sobi3ch

19

Для невеликих завдань, таких як ця, замість створення сценарію створіть псевдонім на зразок цього,

$ alias cdproj='cd /dir/web/www/proj'

Ви повинні додати це у свій .bashrcфайл, якщо ви хочете, щоб він встановлений для кожної інтерактивної оболонки.

Тепер ви можете запустити це як $ cdproj.


1
Ви також можете мати сценарій відлунювати команди, які потрібно виконати, а потім використовувати eval `./script` або eval $(./script)виконувати ці команди. Це загальний підхід для команд, які потребують оновлення середовища оболонки виклику.
Кіт Томпсон

2
Будьте дуже уважні до того, що ви отримаєте, якщо ви збираєтесь піти на evalпідхід.
jw013

13

Використовуйте exec bashв кінці

Баш сценарій працює в його поточному середовищі або в середовищі своїх дітей, але ніколи в батьківському середовищі.

Однак це запитання часто задають, оскільки хочеться залишитись у рядку bash у певному каталозі після виконання bash-скрипту з іншого каталогу.

Якщо це так, просто виконайте дочірній екземпляр bash в кінці сценарію:

#!/usr/bin/env bash
cd desired/directory
exec bash

Це створює нову підшару. Введіть, exitщоб повернутися до першої оболонки, де спочатку був запущений сценарій.


Краще просто джерело сценарію, як у прийнятій відповіді: використання execзазвичай вважається останнім засобом негідника .. :)
нейронет

1
цей фокус не працює в debian 9 stretch.
вдегенне

3
Це неправильний шлях для цього!
Денніс Вільямсон

4
Оскільки ніхто не деталізував проблеми з цим (я дивлюся на вас, @Dennis): (1) Кожен раз, коли ви запускаєте це, це створює новий, стійкий процес баш. Зробіть це десять або двадцять разів за сеанс, і у вас буде нагромаджено від 11 до 21 баш-процесів. Це може вплинути на продуктивність, і, якщо ви спробуєте чисто припинити сеанс, набравши exit(або Ctrl + D), вам доведеться це зробити від 11 до 21 разів. (2) Ще одним недоліком використання виконуваного сценарію є те, що якщо ви встановите будь-які параметри оболонки (наприклад,  dotglobабо  globstar) під час свого інтерактивного сеансу оболонки, ви втратите їх, оскільки ви запускаєте нову оболонку.
G-Man каже "Відновити Моніку"

1
Дуже приємне рішення! Я переписав псевдонім у bash_profile, тому тепер це сценарій, що зберігається в окремому файлі. Я використовую сценарій для переходу до новоствореної тимчасової папки. А зараз ще простіше провести тимчасовий баш-сеанс. SRP в дії! Дякую!
artyom.razinov

8

Хоча є відповіді, які виконують саме ту дію, яку ви хочете, більш стандартним методом для цієї мети є створення символічного посилання:

ln -s ~/web/www/project proj   #use full path to dir!

Тоді ви можете cdпотрапити в каталог із використанням імені proj:

cd proj

Цей метод є більш гнучким, оскільки ви можете отримати доступ до файлів, використовуючи коротке ім'я, без cd:

ls proj/   #note the endslash!
vim proj/file.x

4

Якщо ви переходите між каталогіми далеко у файловій системі. Я порекомендую автоемп .


4

Залежно від того, що ви збираєтеся робити, іншим рішенням може бути створення функції замість сценарію.

Приклад:

Створіть функцію у файлі, скажімо так /home/aidin/my-cd-script:

function my-cd() {
  cd /to/my/path
}

Потім включіть його у свій файл bashrcчи zshrcфайл:

# Somewhere in rc file
source /home/aidin/my-cd-script

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

$ my-cd

0

Чому б не використовувати "exec", що робиться, щоб зробити саме те, що я бажаю.

#!/bin/bash

cd someplace
exec bash

~/someplace

1
Остерігайтеся речей, які здаються такими, які ви хочете. (Гігантський дерев’яний кінь! Просто те, що я хотів!) Кожен раз, коли ви запускаєте це, це створює новий, стійкий процес башти. Зробіть це десять-двадцять разів за сеанс, і у вас буде складено 11 - 21 баш-процесів. Це може вплинути на продуктивність, і, якщо ви спробуєте чисто припинити сеанс, набравши exit(або Ctrl + D), вам доведеться це зробити від 11 до 21 разів.
G-Man каже: "Відновіть Моніку"

Я точно міг бачити, де це буде проблемою. Для мене, хоча я використовую це один раз, виконуючи потрібну мені роботу, а потім виходжу. Якщо це єдиний недолік, я можу з цим жити. З іншого боку, якщо є краще рішення, я готовий його переглянути.
Павло

Відповідь Ейдіна на це запитання за допомогою функції оболонки та відповідь Сахіна Дівекара за псевдонімом (IMO) є кращими рішеннями, ніж використання сценарію. PS Ще одним недоліком використання сценарію є те, що якщо ви встановите будь-які параметри оболонки (наприклад,  dotglobабо  globstar), ви втратите їх, оскільки ви запускаєте нову оболонку. … (Продовжував)
G-Man каже: «Відновіть Моніку»

(Продовжував) ... PPS Я щойно помітив, що ви, в основному, повторюєте відповідь Сержа Стройбандта і говорили: "Чому б цього не зробити?". На  стек-біржі ми очікуємо відповіді, щоб дати нові ідеї та / або інформацію, а не просто обговорити. інші відповіді.
G-Man каже "Відновити Моніку"

-1

Це можна зробити за допомогою функції або за допомогою && Наведені нижче приклади встановлюють Zabbix та створюють файл із рядком всередині нього.

Наприклад:

#!/bin/bash

# Create Function:
installZabbix(){
    cd /usr/src/zabbix-4.2.4;
    ./configure --enable-agent;
    make install;
    cd /usr/src/;
    >file;
    echo "Hi, this is a file." >>file;
}

# Call the function:
installZabbix

або:

#!/bin/bash
cd /usr/src/zabbix-4.2.4 && ./configure --enable-agent && make install && cd /usr/src && >file && echo "Hi, this is a file." >>file
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.