Псевдоним к CD в каталоге и вызов команды

21

У меня есть .bash_profileи в этом у меня есть набор псевдонимов. Эти псевдонимы в настоящий момент выполняют только одну команду, и это было довольно легко. Однако я хотел бы сделать две вещи с новым псевдонимом, который я пытаюсь создать.

  1. CD в ​​каталог
  2. Запустите команду из этого каталога
user232103
источник

Ответы:

26

Чтобы выполнить команду с определенным рабочим каталогом, обычно

( cd directory && utility )

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

Пример:

( cd / && echo "$PWD" )  # will output "/"
echo "$PWD"              # will output whatever directory you were in at the start

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

Для конкретного каталога и утилиты можно сделать

alias cdrun='( cd "$HOME/somedir" && ./script.sh )'

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

cdrun () {
    ( cd "$1" && shift && command "$@" )
}

или

cdrun () (
    cd "$1" && shift && command "$@"
)

Замена фигурных скобок с круглыми скобками вокруг тела функции заставляет функцию выполняться в ее собственной подоболочке.

Это будет использоваться как

$ cdrun "$HOME/somedir" ./script.sh

который будет запускать скрипт, script.shрасположенный в каталоге $HOME/somedir, с $HOME/somedirрабочим каталогом, или

$ cdrun / ls -l

который предоставит вам список каталогов в «длинном формате» корневого каталога.

Функция оболочки получает первый аргумент и пытается перейти в этот каталог. Если это работает, он удаляет имя каталога из позиционных параметров (список аргументов командной строки) и выполняет команду, заданную остальными аргументами. commandявляется встроенной командой в оболочке, которая просто выполняет свои аргументы как команду.


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

alias thing='$HOME/somedir/script.sh'

но это будет работать script.shрасположено в $HOME/somedirс текущим каталогом в качестве рабочего каталога.

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

PATH="$PATH:$HOME/somedir"

Теперь script.shв $HOME/somedirсможет быть запущен из любого места, используя только

$ script.sh

Опять же, это не меняет рабочий каталог для команды.

Кусалананда
источник
2
Отличный, исчерпывающий ответ. Я просто думал , что я упомяну , что определение функции требуется только один способ группировки команд и скобки для подоболочки достаточно: cdrun () ( cd "$1" && shift && command "$@" ).
Энтони Дж. - правосудие для Моники
2
@AnthonyGeoghegan Ах, это правда. Я всегда использую { ... }для согласованности с более длинными функциями, хотя.
Кусалананда
Эти вопросы и ответы, кажется, говорят о моей ситуации, и могут быть улучшением при использовании окружения pushdи popd(также, > /dev/nullесли вы пытаетесь также избежать выходных сообщений), при этом сохраняя контекст в чистоте!
Пизис
1
@Pysis Да, (cd dir && thing)также гораздо более портативен, чем использование pushdи popd.
Кусалананда
@ Kusalananda Правда? Я заставил их работать по крайней мере для нескольких систем.
Пизис
4
alias <name-of-the-alias>='cd <the-directory> && <command>'

Итак, если вы хотите изменить каталог (cd) на папку, /var/log/а затем перечислить (ls) ее файлы, вы можете добавить в свой .bash_profileфайл следующее:

alias logs='cd /var/log/ && ls'
Nikolas
источник
1

Я использую эту функцию для запуска одной команды в другом каталоге:

cd1 () {
  if [ $# -eq 1 ]; then
    command cd -- "$1"
  else
    ( command cd -- "$1" && shift && "$@" )
  fi
}

Ограничение этой функции заключается в том, что подстановочные знаки заполнены относительно исходного каталога, а не относительно каталога, в котором выполняется команда. Это можно сделать лучше в Zsh .

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

Жиль "ТАК - перестать быть злым
источник
-1

Разделяйте команды точкой с запятой, например:

alias do_something='cd /tmp; ls'
Джон Эллиот V
источник
8
Если cdпроизойдет сбой, вы получите неправильный каталог. Лучше использовать, &&а не ;здесь.
Кусалананда
@ Кусалананда прав. Вы можете найти больше в этом ответе
nikolas