Может ли ',,' быть псевдонимом для '..'?

41

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

$ alias ,,=..
$ cd ,,
-bash: cd: ,,: No such file or directory
килоджоулей
источник
6
Псевдоним - это программа для запуска, а не аргумент для программы; так $ ,,жаловался бы, как таковой bash: ..: Is a directory. (Другими словами, это не исполняемый файл.)
jpaugh
5
@jpaugh: более ясный способ сказать, что: расширение псевдонима происходит только в первом «слове» команды. Как вы говорите, он работает только для имен команд, а не для аргументов. (И вы не могли даже alias 'cd ,,'='cd ..'. Ну, вы могли бы, но вам нужно было бы выполнить это, cd\ ,,чтобы сделать все это одним словом.)
Питер Кордес
5
Рассмотрим зш. Он имеет глобальные псевдонимы, alias -g ,,=..и cd ,,работает так, как вы ожидаете.
Муру
1
Боковое мышление: find / -type d -exec ln -s .. {}/,, \;... ;-)
Тоби Спейт
2
Имхо: не делай этого. Использование псевдонимов для сокрытия типографских ошибок - плохая практика. Эти ошибки могут закончиться копированием кода или скринкастами. Это не будет работать на других хостах или аккаунтах. И такая модификация (в зависимости от того, как она реализована) может привести к другим, неожиданным, трудным для устранения ошибок. Мое предложение: если вы неправильно набрали команду, просто введите ее еще раз ;-).
jjmontes

Ответы:

45

ЗШ:

Если вы используете zsh alias -g ,,=".."то, что вам нужно, но это приведет к тому, что «,,» будет расширяться везде, а не только при использовании с cd.

От man zshbuiltins:

Если -g флаг присутствует, определите глобальный псевдоним; глобальные псевдонимы расширяются, даже если они не встречаются в командном положении.

BASH:

Если ограничено bash(поскольку вопрос помечен как ), прочитайте следующее:

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

Цитирование man bash:

Если последний символ значения псевдонима является пустым, то следующее слово команды, следующее за псевдонимом, также проверяется на расширение псевдонима.

Поэтому достаточно псевдоним cdс дополнительным пробелом (чтобы разрешить расширение его следующего аргумента), а затем псевдоним ,,для ... Видеть, что

alias cd='cd '
alias ,,='..'

дает именно то, что вам нужно.

Обратите внимание, что это верно не только для bash(и его aliasреализации), но и для всех POSIX-совместимых оболочек. Цитируя пример из man 1p alias(руководство не описывает эту функцию явно, только через пример):

  1. Настройте nohup так, чтобы он мог иметь дело с аргументом, который сам по себе является псевдонимом:

           alias nohup="nohup "

Предупреждение: как пишет @PeterCordes в своем комментарии, это автоматически приведет к расширению других псевдонимов при записи после cd. Это может потребовать от вас написать, cd \grepесли вы хотите изменить каталог на один с именем, grepно ваш grepпсевдоним для grep --color=auto. Без обратной косой черты cdсообщит об ошибке «слишком много аргументов» (вы не можете одновременно работать cdс двумя каталогами) !.

пенополистирол летать
источник
22
Это умный, но противный взлом. Я бы не хотел этого делать; слишком легко, чтобы случайно тебя укусить. например, если у вас есть псевдоним для команды, которую вы обычно запускаете, и вы хотите cdвойти в каталог с его исходным кодом. Или другие конфликты между вашими псевдонимами и общими именами каталогов. Как cd drбы расширяться cd disown -rдля меня, с этим псевдонимом. В любом случае, гораздо лучше переопределить встроенную cdфункцию для подобных вещей, IMO.
Питер Кордес
8
+1 для решения чистого псевдонима (я кое-что узнал). В то же время я согласен с комментарием Питера. Я думаю, что к вашему ответу следует добавить какое-то явное предупреждение.
Камиль Мачоровски
58

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

cd () { if [ "$1" = ",," ]; then builtin cd ..; else builtin cd "$@"; fi; }

Или с комментариями и красивым форматированием:

cd ()
{
  if [ "$1" = ",," ]; then  # if first argument is ",,"...
    builtin cd ..           # call the builtin cd with ".." instead...
  else
    builtin cd "$@"         # else call builtin cd with original arguments 
  fi
}

РЕДАКТИРОВАТЬ

Спасибо @derobert за указание, что if then elseздесь лучше, чем && ||. Кроме того, я только что понял ( * facepalm *), что эта реализация будет работать только в том случае, если какие-либо аргументы без пути (т.е. -L -P) не являются первым аргументом. Так что будьте осторожны, если у вас есть плохая привычка печатать, cd -L ,,это не поможет вам. И я думаю, что с этим нетривиально обращаться правильно.

BenjiWiebe
источник
16
@BenjiWiebe Я думаю, что версия с «комментариями и красивым форматированием» была бы лучше с if-then-else.
zwol
Вау, ребята, много хороших идей. Я вижу, вы используете функцию редактирования, чтобы позаботиться о необходимых исправлениях. Я не тратил много времени на его тестирование. :)
BenjiWiebe
1
В качестве альтернативы, просто перезапишите $1перед выполнением встроенного:cd () { [ "$1" = ",," ] && set .. ; cd "$@"; }
Тоби Спейт
1
@TobySpeight set .. "${@:2}", или вы что-то потеряете после первого аргумента.
chepner
8
Кроме того, технически ..не должно быть первым аргументом; cdв bashможет принимать различные варианты ( -P, -L, -@, -e).
chepner
29

Псевдонимы должны быть первым словом команды. Кроме того, псевдоним должен быть заменен на слово, поэтому без пробелов).

Справочное руководство Bash: псевдонимы

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

Вы могли бы псевдоним как ..и ,,быть cd ...

$ alias ..="cd .."
$ alias ,,="cd .."
$ cd /tmp && pwd
/tmp
$ ,, && pwd
/
Стивен
источник
Это именно то, что я делаю! : D эти две точки / запятые гораздо проще набрать, чемcd ..
rav_kr
10
+1, это неплохая идея. Другой способ сделать это .. в Bash - использовать shopt -s autocdлюбой каталог, просто введя его имя. Конечно, вы все еще псевдоним для,,
ilkkachu
Я тоже :-)
joeytwiddle
3

Еще один способ сделать ..изменить каталог, чтобы включить в Bash autocd функции :

shopt -s autocd 

Это автоматически изменит каталог, когда вы введете имя одного:

~$ /tmp
cd /tmp
/tmp$ 

Вы все еще должны сделать псевдоним для, ,,но это может быть сделано только сalias ,,=..

ilkkachu
источник
2

Уже есть приложение для этого: https://github.com/shyiko/commacd (нет связи со Стэнли Шуйико).

commacdэкспортирует три команды: ,(для прыжка вперед), ,,(назад) и ,,,(назад + вперед):

Все трое сначала пытаются найти соответствие по префиксу. Только если результаты не найдены, они отступят к подстроке (нечеткому) соответствию

Чтобы ответить на ваш вопрос, скрипт добавляет псевдонимы к трем функциям, которые он определяет:

alias ,=_commacd_forward
alias ,,=_commacd_backward
alias ,,,=_commacd_backward_forward
Доктор Дао
источник