Есть ли один слой, который позволяет мне создавать каталог и перемещаться в него одновременно?

Я часто повторяю:

 mkdir longtitleproject
cd longtitleproject

Есть ли способ сделать это в одной строке без повторения имени каталога? Я нахожусь здесь.

118 голосов | спросил Duopixel 12 MaramSat, 12 Mar 2011 04:15:44 +03002011-03-12T04:15:44+03:0004 2011, 04:15:44

10 ответов


135

Нет встроенной команды, но вы можете легко написать функцию, которая вызывает mkdir, затем cd:

mkcd () {
  mkdir "$1"
  cd "$1"
}

Поместите этот код в ваш файл ~/.bashrc (или ~/.kshrc для пользователей ksh или ~/.zshrc) для zsh). Он определяет функцию, называемую mkcd. "$1" будет заменен аргументом функции при ее запуске.

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

  • Вы не можете сразу создать цепочку подкаталогов. Исправить: передать -p вариант mkdir. (Это может быть или не быть желательным, поскольку это увеличивает риск того, что опечатка не обнаружена, например mkcd mydierctory/newsub будет с радостью создавать mydierctory и mydierctory/newsub, когда вы хотели создать newsub внутри существующего mydirectory.)
  • Если аргумент начинается с -, но не просто -, то mkdir и cd будет интерпретировать это как вариант. Если это просто -, то cd будет интерпретировать его как означающий $OLDPWD. Если это +, за которым следуют 0 или более цифр, тогда cd в zsh будет интерпретировать его как индекс в стеке каталога. Вы можете исправить первую проблему, но не две другие, передав -- перед аргументом. Вы можете исправить все эти проблемы, добавив ./ к аргументу, если это относительный путь.
  • mkdir не соответствует CDPATH, но cd делает, поэтому, если вы установили CDPATH в значение, которое не начинается с . (по общему признанию, несколько необычной конфигурации), тогда cd может привести вас к другому каталогу, чем тот, который был только что создан. Превращение ./ в относительные пути исправляет это (это приводит к игнорированию CDPATH).
  • Если mkdir не работает, он пытается выполнить cd. Исправление: используйте && для разделения двух команд.

Все еще довольно просто:

 mkcd () {
  case "$1" in /*) :;; *) set -- "./$1";; esac
  mkdir -p "$1" && cd "$1"
}

Эта версия все еще имеет потенциал, чтобы сделать cd перейдите в другой каталог из того, что только mkdir в одном случае края: если аргумент mkcd содержит .. и проходит через символическую ссылку. Например, если текущий каталог /tmp/here и mylink является символической ссылкой на /somewhere/else, тогда mkdir mylink/../foo создает /somewhere/else/foo, тогда как cd mylink/../foo изменяется на foo. Недостаточно искать символические ссылки в аргументе, потому что оболочка также отслеживает символические ссылки в своем текущем каталоге, поэтому cd /tmp/mylink; mkdir ../foo; cd ../foo не переходит в новый каталог (/somewhere/else/foo), а в /tmp/foo. Исправить это, чтобы позволить встроенному cd разрешать все компоненты пути .. (не имеет смысла использовать код foo/..

Мы приходим к этой надежной, если немного версии gory:

 mkcd () {
  case "$1" in
    */..|*/../) cd -- "$1";; # that doesn't make any sense unless the directory already exists
    /*/../*) (cd "${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd -- "$1";;
    /*) mkdir -p "$1" && cd "$1";;
    */../*) (cd "./${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd "./$1";;
    ../*) (cd .. && mkdir -p "${1#.}") && cd "$1";;
    *) mkdir -p "./$1" && cd "./$1";;
  esac
}

(упражнение: почему я использую подоболочку для первого вызова cd?)

  

Если mkdir терпит неудачу, я хочу быть уверенным не изменять текущий каталог. Изменение с помощью cd - или $ OLDPWD недостаточно хорошо, если оболочка не имеет разрешения на изменение в свой текущий каталог. Кроме того, вызов cd обновляет OLDPWD, поэтому мы хотим сделать это только один раз (или восстановить OLDPWD).


Есть также менее специализированные способы не перепечатывать слово из предыдущей строки:

  • Введите cd , затем Esc . (или Alt + . ) для вставки последнего аргумента из предыдущей команды.
  • cd !$ выполняет cd в последнем аргументе предыдущей команды.
  • Нажмите Вверх , чтобы вызвать предыдущую командную строку, затем отредактируйте ее, чтобы изменить mkdir на cd.
ответил Gilles 12 MaramSat, 12 Mar 2011 04:26:49 +03002011-03-12T04:26:49+03:0004 2011, 04:26:49
105

Это один лайнер, который вам нужен. Никакой другой конфигурации не требуется:

mkdir longtitleproject && cd $_

Переменная $_, в bash, является последним аргументом, заданным предыдущей командой. В этом случае имя созданного вами каталога. Как объясняется в man bash:

_         At  shell  startup,  set to the absolute pathname used to invoke
          the shell or shell script being executed as passed in the  envi‐
          ronment  or  argument  list.   Subsequently, expands to the last
          argument to the previous command, after expansion.  Also set  to
          the  full  pathname  used  to  invoke  each command executed and
          placed in the environment exported to that command.  When check‐
          ing  mail,  this  parameter holds the name of the mail file cur‐
          rently being checked."$_" is the last argument of the previous command.

Используйте cd $_ для извлечения последнего аргумента предыдущей команды вместо cd !$, потому что cd !$ дает последний аргумент предыдущей команды в истории оболочки :

cd ~/
mkdir folder && cd !$

вы попадаете домой (или ~ /)

cd ~/
mkdir newfolder && cd $_

вы попадаете в новую папку под домом !! (или ~ /новая папка)

ответил Jesús Carrera 1 PM00000020000002731 2015, 14:21:27
27

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

$ mkdir someDirectory<ENTER>
$ cd !$

, где bash любезно заменяет !$ последним словом последней строки; то есть введенное длинное имя каталога.

Кроме того, завершение имени файла является вашим другом в таких ситуациях. Если ваш новый каталог был единственным файлом в папке, быстрый двойной TAB предоставит вам новый каталог без повторного ввода его.

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

ответил Rob 15 MarpmTue, 15 Mar 2011 22:56:54 +03002011-03-15T22:56:54+03:0010 2011, 22:56:54
15

По Что настройки, выполненные в профиле оболочки, чтобы повысить производительность? , вот как я это делаю:

# make a directory and cd to it
mcd()
{
    test -d "$1" || mkdir "$1" && cd "$1"
}

это означает, что он также работает, если каталог уже существует.

ответил Mikel 12 MaramSat, 12 Mar 2011 06:21:01 +03002011-03-12T06:21:01+03:0006 2011, 06:21:01
8

Если вы используете Oh My Zsh, есть команда под названием take , которая делает именно это. Это будет выглядеть примерно так.

take myfolder

Я действительно нашел это случайно. Я просто посмотрел, и он указан на этот чит-код из вики-страницы Oh My Zsh GitHub. Это довольно полезная команда и, по-видимому, очень легко создать себя.

ответил Jordan Harris 20 AM000000100000002631 2015, 10:31:26
3

Или вы могли бы просто создать короткую переменную «на лету» и использовать ее дважды x = longproject ; mkdir $x ; cd $x, который я допускаю, еще длиннее, чем использование функции shellscript:)

ответил sakisk 12 MarpmSat, 12 Mar 2011 13:33:19 +03002011-03-12T13:33:19+03:0001 2011, 13:33:19
0

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

https: //gist.github. com /rehnen /34236d6ff270ccaa74b6 # mkdir-like-it-was-them-be-be

ответил Marcus Rehn 23 WedEurope/Moscow2015-12-23T15:29:38+03:00Europe/Moscow12bEurope/MoscowWed, 23 Dec 2015 15:29:38 +0300 2015, 15:29:38
0

Вот небольшой вариант, который стоит упомянуть:

function mkdir() {
    local dir=$1
    command mkdir "$dir"  &&  cd "$dir"
}

Добавьте это в свой ~/.bash_profile, и затем вы можете использовать mkdir как обычно (после того, как у вас есть source 'd it) , за исключением того, что теперь он будет выполнять функцию выше, а не стандартную команду mkdir.

Примечание. Это не подтверждает ввод в соответствии с принятым ответом Жиля , но демонстрирует, как вы можете ( эффективно) переопределить встроенные функции.

Из документов (слегка перефразируя) :

  

command mkdir [args] запускает mkdir с args, игнорируя любую функцию оболочки с именем mkdir

Я считаю, что builtin достигает аналогичного результата с помощью команды command.

ответил Arj 6 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowWed, 06 Sep 2017 20:18:26 +0300 2017, 20:18:26
0

Добавление вспомогательной функции в BASH, ZSH или KSH

Создайте команду mkcd для вашей среды в одной строке

echo -e 'mkcd() {\n mkdir -p "$1" && cd $_\n}' >> ~/.${0//-/}rc && . ~/.${0//-/}rc
ответил Proximo 14 J000000Saturday18 2018, 18:22:44
-1

Просто автоматизировал приведенные выше ответы и выполнил одноразовый исполняемый скрипт:

fun='
mkcd ()
{
    mkdir -p -- "$1" && cd -P -- "$1"
}'

echo "$fun" >> ~/.bashrc

Просто скопируйте это в новый файл mkcd.sh и запустите его только один раз в терминале с помощью bash mkcd.sh. Затем выполните source ~/.bashrc, чтобы он работал в текущем сеансе.

После этого вы можете использовать mkcd some_dir для создания и ввода непосредственно в этот каталог.

ответил subtleseeker 11 MonEurope/Moscow2017-12-11T23:24:56+03:00Europe/Moscow12bEurope/MoscowMon, 11 Dec 2017 23:24:56 +0300 2017, 23:24:56

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132