Я не могу сказать, сколько раз я хотел получить команду, которая будет одновременно создавать каталог и перемещаться в этот каталог. В принципе, я хотел бы эквивалент следующего:
mkdir -p /arbitrarily/long/path; cd /arbitrarily/long/path
но нужно набрать только /arbitrarily/long/path
один раз, что-то вроде:
mk-cd /arbitrarily/long/path
Я попытался создать сценарий, чтобы сделать это, но он только изменяет каталог в сценарии. Я бы хотел, чтобы каталог в оболочке также изменился.
#!/bin/bash
mkdir $1
cd $1
export PWD=$PWD
Как я могу сделать это?
cd
, вы выбрали специальный случай с самого начала. : Dcd
информация (возврат к предыдущему каталогу с использованиемcd -
, использованиемpushd
иpopd
поддержкой «стека» каталогов): superuser.com/questions/324512/…mkdir -p /very/long/path
, затем использоватьcd
пробел и затем нажать Alt +,.
чтобы повторить последний аргумент, то есть имя dir.mkdir -p /very/long/path; cd !#:2
. Строка!#:2
расширится до аргумента nr. 2 (то есть третий аргумент/very/long/path
, так как отсчет начинается с нуля).!$
. Я постоянно использую этот трюк, хотя с расширением истории можно сделать гораздо больше .Ответы:
Самый простой способ - использовать функцию оболочки:
Поместите его в свой
.bashrc
файл, чтобы сделать его доступным вам, как и другую команду оболочки.Причина, по которой он не работает как внешний сценарий, заключается в
cd
том, что текущий каталог исполняемого сценария изменяется, но не влияет на вызывающий. Это по замыслу! Каждый процесс имеет свой собственный рабочий каталог, который наследуется его дочерними элементами, но обратное невозможно.Если только часть конвейера не выполняется в фоновом режиме или явно в подоболочке, функция оболочки запускается не в отдельном процессе, а в том же самом, как если бы команда была получена. Текущий каталог оболочки может быть изменен функцией.
&&
Используется здесь , чтобы отделить обе команды , используемые средства, если первая команда успешно (mkdir
), запустить второй (cd
). Следовательно, еслиmkdir
не удается создать запрошенный каталог, нет смысла пытаться зайти в него. Сообщение об ошибке печатаетсяmkdir
и все.-p
Параметр , используемый сmkdir
там , чтобы сказать эту утилиту , чтобы создать недостающий каталог , который является частью полного пути имени каталога , переданным в качестве аргумента. Одним из побочных эффектов является то, что если вы попросите создать уже существующий каталог,mkcd
функция не сработает, и вы окажетесь в этом каталоге. Это может рассматриваться как проблема или особенность. В первом случае функция может быть изменена, например, таким способом, который просто предупреждает пользователя:Без
-p
опции поведение исходной функции было бы совсем другим.Если каталог, содержащий каталог для создания, еще не существует, происходит
mkdir
сбой, также как и функция.Если каталог для создания уже существует, происходит
mkdir
сбой иcd
не вызывается.Наконец, обратите внимание, что установка / экспорт
PWD
бессмысленна, поскольку оболочка уже делает это внутренне.Редактировать: я добавил
--
опцию в обе команды для функции, чтобы имя каталога начиналось с тире.источник
~/.bashrc
один из других сценариев инициализации.alias mk-cd 'mkdir -p \!:1; cd \!:1'
без функции? Или, может быть, мне стоит начать думать о функциях bash, скорее о расширенных псевдонимах?csh
механизм передачи аргументов не реализован с псевдонимами в стиле Борна. Функции - действительно путь, будучи намного более гибким.bar
). Другой вариант - использоватьhistory 1
, как вalias mk-cd='args="$(history 1)" && args="${args#*mk-cd\ }" && mkdir -p "$args" && cd'
- это прекрасно работает для примера спрашивающего, но не является общим решением, так как любые другие команды в той же строке (например, передача вывода) приведут к сбою.Я хотел бы добавить альтернативное решение.
Ваш скрипт будет работать, если вы вызовете его с помощью команды
.
илиsource
:Если вы сделаете это,
export
в сценарии нет необходимости. Вы можете обойти ввод.
, используяalias
:Причина, по которой это работает, заключается в том, что скрипт обычно выполняется в под-оболочке, поэтому его среда теряется при завершении, но команда
.
(илиsource
) заставляет его запускаться в текущей оболочке.Этот метод может быть полезен для последовательностей команд, которые слишком сложны для функции или находятся в стадии разработки и часто редактируются: после того,
alias
как они введены.bash_aliases
, вы можете редактировать скрипт по своему усмотрению без повторной инициализации.Обратите внимание на следующее: -
Если вы пишете скрипт, который должен быть вызван командой
.
/source
, есть два способа убедиться в этом: -По какой-то причине сценарий, вызываемый с помощью
.
/,source
не должен быть исполняемым, поэтому просто удалите это разрешение, и сценарий либо не будет найден в «$ PATH», либо выдаст ошибку разрешения, если будет вызван с явным путем.В качестве альтернативы можно использовать следующий трюк в начале скрипта:
Это работает, потому что в под-оболочке
bind
выдается предупреждение, хотя нет статуса ошибки: следовательноread
, используется, чтобы выдавать ошибку при отсутствии ввода.источник
.
. Я делал. .bashrc
бесчисленное количество раз, но не знал, что именно.
делает. Это похоже наexport
?export var
копирует внутреннюю переменнуюvar
в среду, где она наследуется и импортируется как переменная в любой вложенной оболочке, но не влияет на родительскую оболочку. Обычно для запуска скрипта создается под-оболочка, и любые изменения, которые он делает (включая экспортированные переменные), теряются при его завершении. Чтобы скрипт устанавливал переменные в оболочке, он должен запускаться в этой оболочке, и это то, что.
делает команда: запускать сценарий без создания вложенной оболочки. Любопытно, что выполняемые сценарии.
не обязательно должны иметь разрешение на выполнение..
иexport
команд, название этого вопроса не приведет вас ожидать ответ здесь, так что я дам свой ответ стенд , как это, но спасибо за ваш комментарий.Не одна команда, но вам не нужно заново вводить весь путь, который вы используете
!$
(это последний аргумент из предыдущей команды в истории оболочки).Пример:
источник
Создавая псевдонимы . Очень популярный способ создавать свои собственные команды.
Вы можете создать псевдоним на лету:
Вот и все. Если вы хотите сохранить этот псевдоним постоянно (а не только в текущем сеансе), поместите эту команду в точечный файл (обычно ~ / .bash_aliases или ~ / .bash_profile).
источник
В дополнение к тому, что уже было предложено, я бы порекомендовал thefuck . Это среда Python для оптимизации процесса оболочки путем исправления ошибок. Вдохновленный этим сообщением , все, что вам нужно сделать, это ввести настроенный псевдоним (по умолчанию
fuck
), и он попытается исправить вашу предыдущую команду. Одно из его исправлений ведет себя следующим образом:источник