изменение текущего рабочего каталога с помощью скрипта

8

Я прочитал этот вопрос и ответ, но он не подходит для моей проблемы, даже если он похож.

Я пишу скрипт (называется cpj), который запустит один из моих текущих проектов. У меня около 5 из них. Когда я печатаю

$ cpj blah

Я хочу, чтобы текущий рабочий каталог изменился на каталог проекта blah (который я храню в $ PROJDIR), и я хочу, чтобы emacsclient открыл основной файл для этого проекта (который я держу в $ MAINFILE).

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

Чтобы проверить это, я написал сценарий оболочки (называемый chcwd), который имеет одну строку:

cd $1

Если из командной строки я делаю:

$ . chcwd $PROJDIR

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

. chcwd $PROJECT

это не изменит текущий рабочий каталог оболочки. Я понимаю, что я запускаю 2 сценария (cpj, а затем chcwd) и таким образом создаю 2 оболочки, но не вижу способа выполнить то, что я хочу. Может кто-нибудь показать мне, как достичь своей цели?

Гай
источник

Ответы:

11

Ты не можешь съесть свой торт и съесть его. Здесь происходят две вещи: выполнение скрипта в новой оболочке и импорт строк скрипта для запуска в текущей оболочке. Используя оператор точки (который является псевдонимом для sourceкоманды), вы фактически запускаете код в текущей оболочке . Если ваш код выбирает cd, когда это будет сделано, вы останетесь в новом каталоге.

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

Если вы часто этим пользуетесь и хотите, чтобы его эффекты остались в текущей оболочке, возможно, вы могли бы вместо этого написать свой «скрипт» в виде функции оболочки и сохранить его в своем ~ / .profile или другом rc-файле оболочки.

function cpj() {
    # code here
    cd /path/$1
    emacs file_name
}
Калеб
источник
Калеб, спасибо за ваш вклад. Мне нравится твой каламбур. Ваш первый абзац превосходно повторяет то, что я сказал в своем вопросе. Ваш второй абзац повторяет то, что было сказано в вопросе, который я очень хорошо процитировал. Твой третий абзац именно то, что я искал! Спасибо чувак.
Bev
2

У меня есть аналогичный сценарий, написанный для личного использования. Существует очень простой способ добиться изменения рабочего каталога внутри скрипта. Сначала просто напишите свой сценарий, in.ex .:

#!/bin/bash

case $1 in
     project1) cd /home/me/work/customer1/project1
     ;;
     project2) cd /home/me/work/customer2/project1
     ;;
     project3) cd /home/me/work/customer3/project2
     ;;
     project4) cd /home/me/work/customer4/project5
     ;;
     *) echo "Usage: cdto cd_profile_name"
     ;;
esac

Теперь давайте предположим, что скрипт называется 'cdto'. Чтобы заставить его работать, вы должны поместить его в текущую оболочку, чего можно добиться с помощью 'source' или '.' команда (оба одинаковы). Например:

. cdto project1

Теперь, чтобы сделать его более удобным:

  1. Скопируйте скрипт 'cdto' в каталог 'bin' вашей учетной записи (например, / home / johnsmith / bin - создайте его, если он не существует). Проверьте переменную PATH, чтобы убедиться, что каталог bin включен:

    echo $ PATH

Если нет, отредактируйте ваш файл .profile и добавьте:

if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi
  1. Добавьте псевдоним в ваш файл .bashrc или .bash_aliases:

    псевдоним cdto = '. cdto»

И это сделано. После следующего входа в систему или при открытии нового терминала вы можете просто использовать in.ex .:

cdto project1

Наслаждаться :-)

Себастьян Пих

Себастьян Пих
источник
0

Простой трюк для этого:

pushd $PROJDIR && bash

Теперь рабочий каталог - $ PROJECT.

artificerpi
источник