Как заставить команду cd вступить в силу вне подоболочки bash-скрипта?

Я сделал этот скрипт:

#!/bin/bash if [[ $# -ne 1 ]]; then echo "only use one argument" exit 1 fi mkdir $1 sleep 0.5 cd $1 exit 0 

Я хотел создать скрипт, который позже поместил бы в / usr / bin, чтобы всякий раз, когда я пишу crdir asd он создавал каталог и автоматически crdir asd мой текущий каталог на новый каталог.

Этот способ не работает, потому что скрипт Schell, по-видимому, является подоболочкой, а команда cd не будет действовать вне подоболочки, так как бы я это сделал?

Я читал в Интернете, что я должен «найти» его, запустить его с точкой впереди, как . ./crdir asd . ./crdir asd , но, во-первых, когда я попробовал это, ssh отключился от машины, и, во-вторых, это не сработало так, как я хотел, чтобы это работало, как команда.

Какие-нибудь советы?

РЕДАКТИРОВАТЬ: я также пробовал mkdir aaa; cd !# mkdir aaa; cd !# но это не сработало, это !# приняло аргумент предыдущей команды.

Сделайте это вместо функции:

 crdir() { if [ "$#" -eq 1 ]; then mkdir -p -- "$1" && cd -P -- "$1" else echo >&2 "Usage: crdir " return 1 fi } 

Который вы можете положить в ваш ~/.bashrc .

Ваш . crdir также будет работать (в bash и других shellх, чьи . могут принимать аргументы), но вам нужно удалить тот exit 0 который приводит к выходу оболочки. Также обратите внимание, что, когда не в режиме POSIX, bash ищет файл для источника в текущем каталоге, если он не может быть найден в $PATH , что делает его немного опасным (на том же уровне, что и при добавлении . Или пустой записи в конец $PATH ).

Также если . crdir . crdir вызывается без аргументов, тогда скрипт унаследует позиционный параметр оболочки. Например, set foo; . crdir set foo; . crdir set foo; . crdir не возвращает ошибку и создает каталог foo .

Несколько других замечаний по вашему сценарию:

 #!/bin/bash 

Обратите внимание, что она получена из файла (просто рассматривается как комментарий).

 if [[ $# -ne 1 ]]; then echo "only use one argument" 

Желательно выводить сообщения об ошибках в stderr ( echo >&2 text ).

  exit 1 fi mkdir $1 

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

Также, если $1 начинается с - , mkdir будет рассматривать его как опцию. Вам нужно будет использовать маркер -- end-of-option, чтобы сообщить mkdir что содержимое $1 не является опцией, даже если оно начинается с - .

Вы также не проверяете, успешно ли выполнена команда mkdir .

Вы также можете использовать опцию -p которая указывает mkdir создать все компоненты каталога, а также заставляет mkdir не возвращать ошибку, если каталог уже существует. Так:

  mkdir -p -- "$1" && 
 sleep 0.5 

Не нужно спать. Вы можете быть уверены, что каталог был создан после успешного возврата mkdir .

 cd $1 

Опять же, у вас есть цитата и - проблемы. Кроме того, в bash вам нужна опция -P для cd чтобы интерпретировать пути так же, как и другие утилиты, такие как mkdir . Так:

  cd -P -- "$1" 

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

 exit 0 

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

Здесь я бы переписал скрипт так:

 if [ "$#" -eq 1 ]; then mkdir -p -- "$1" && cd -P -- "$1" else ! echo >&2 "Usage: crdir " fi 

Как насчет функции:

 crdir() { mkdir $1; cd $1; }