Изменить текущий каталог из Bash-скрипта - PullRequest
169 голосов
/ 17 мая 2009

Можно ли изменить текущий каталог из скрипта?

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

#!/bin/bash
cd /home/artemb

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

Ответы [ 14 ]

197 голосов
/ 17 мая 2009

Когда вы запускаете ваш скрипт, создается новый процесс, который наследует только вашу среду. Когда это заканчивается, это заканчивается. Ваша текущая среда остается такой, какая она есть.

Вместо этого вы можете запустить свой скрипт так:

. myscript.sh

. оценит скрипт в текущей среде, поэтому он может быть изменен

156 голосов
/ 17 мая 2009

Вам необходимо преобразовать ваш скрипт в функцию оболочки:

#!/bin/bash
#
# this script should not be run directly,
# instead you need to source it from your .bashrc,
# by adding this line:
#   . ~/bin/myprog.sh
#

function myprog() {
  A=$1
  B=$2
  echo "aaa ${A} bbb ${B} ccc"
  cd /proc
}

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

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

53 голосов
/ 02 сентября 2009

В свете нечитаемости и чрезмерного усложнения ответов, я считаю, что именно это и должен делать запрашивающий

  1. добавить этот скрипт в PATH
  2. запустить скрипт как . scriptname

. (точка) гарантирует, что скрипт не будет запущен в дочерней оболочке.

38 голосов
/ 16 августа 2010

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

alias your_cmd=". your_cmd"

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

30 голосов
/ 11 мая 2010

Если вы используете bash, вы можете попробовать псевдоним:

в файл .bashrc добавьте эту строку:

alias p='cd /home/serdar/my_new_folder/path/'

когда вы пишете «p» в командной строке, это изменит каталог.

16 голосов
/ 01 марта 2013

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

Если целью является запуск вашей команды: goto.sh / home / test Затем интерактивно работайте в / home / test, запустив интерактивную оболочку bash в вашем скрипте:

#!/bin/bash
cd $1
exec bash

Таким образом, вы будете находиться в / home / test до выхода (выхода или Ctrl + C) из этой оболочки.

13 голосов
/ 17 мая 2009

При pushd текущий каталог помещается в стек каталогов и изменяется на заданный каталог, popd получает каталог поверх стека и затем изменяет его

pushd ../new/dir > /dev/null
# do something in ../new/dir
popd > /dev/null
4 голосов
/ 28 октября 2015

Просто перейдите к

yourusername/.bashrc (or yourusername/.bash_profile on MAC) by an editor

и добавьте этот код рядом с последней строкой:

alias yourcommand="cd /the_path_you_wish"

Затем выйдите из редактора.

Затем введите:

source ~/.bashrc or source ~/.bash_profile on MAC.

теперь вы можете использовать: вашу команду в терминале

3 голосов
/ 04 декабря 2014

В основном мы используем cd.., чтобы вернуться из каждого каталога. Я подумал, чтобы сделать это проще, указав количество каталогов, с которыми вам нужно возвращаться за раз. Вы можете реализовать это, используя отдельный файл сценария с помощью команды alias. Например:

code.sh

#!/bin/sh
 _backfunc(){
 if [ "$1" -eq 1 ]; then
  cd ..
 elif [ "$1" -eq 2 ]; then
  cd ../..
 elif [ "$1" -eq 3 ]; then
  cd ../../..
 elif [ "$1" -eq 4 ]; then
  cd ../../../..
 elif ["$1" -eq 10]; then
  cd /home/arun/Documents/work
 fi
 }
alias back='_backfunc'   

После использования source code.sh в текущей оболочке вы можете использовать:

$back 2 

чтобы вернуться на два шага назад из текущего каталога. Подробно объяснено более здесь . Там также объясняется, как поместить код в ~ / .bashrc, чтобы каждая новая открытая оболочка автоматически получала эту новую команду псевдонима. Вы можете добавить новую команду для перехода к определенным каталогам, изменив код, добавив больше if conditions и другие аргументы. Вы также можете вытащить код из git через здесь .

3 голосов
/ 06 марта 2014

Я сделал скрипт для смены каталога. посмотрите: https://github.com/ygpark/dj

...