it-mot-dan-vi.com

Có một lớp lót nào cho phép tôi tạo một thư mục và di chuyển vào đó cùng một lúc không?

Tôi thấy mình lặp đi lặp lại rất nhiều:

mkdir longtitleproject
cd longtitleproject

Có cách nào để làm điều đó trong một dòng mà không lặp lại tên thư mục? Tôi đang ở đây.

166
methodofaction

Không có lệnh tích hợp, nhưng bạn có thể dễ dàng viết một hàm gọi mkdir sau đó cd:

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

Đặt mã này vào tệp ~/.bashrc (Hoặc ~/.kshrc Cho người dùng ksh hoặc ~/.zshrc Cho người dùng zsh). Nó định nghĩa một hàm gọi là mkcd. "$1" Sẽ được thay thế bằng đối số của hàm khi bạn chạy nó.

Phiên bản đơn giản này có một số khuyết điểm:

  • Bạn không thể tạo một chuỗi các thư mục con cùng một lúc. Khắc phục: chuyển tùy chọn -p Cho mkdir. (Điều này có thể hoặc không được mong muốn, vì nó làm tăng nguy cơ lỗi chính tả sẽ không bị phát hiện, ví dụ: mkcd mydierctory/newsub Sẽ vui vẻ tạo mydierctorymydierctory/newsub Khi bạn định tạo newsub bên trong mydirectory.)
  • Nếu đối số bắt đầu bằng - Nhưng không chỉ là -, Thì mkdircd sẽ diễn giải nó dưới dạng tùy chọn. Nếu chỉ là -, Thì cd sẽ hiểu nó có nghĩa là $OLDPWD. Nếu đó là + Theo sau là 0 hoặc nhiều chữ số, thì cd trong zsh sẽ hiểu nó là một chỉ mục trong ngăn xếp thư mục. Bạn có thể khắc phục sự cố đầu tiên, nhưng không phải là hai vấn đề khác, bằng cách chuyển -- Trước đối số. Bạn có thể khắc phục tất cả các vấn đề này bằng cách thêm ./ Cho đối số nếu đó là đường dẫn tương đối.
  • mkdir không theo CDPATH, nhưng cd thì có, vì vậy nếu bạn đã đặt CDPATH thành giá trị không bắt đầu bằng . (Một cấu hình hơi bất thường được thừa nhận), sau đó cd có thể đưa bạn đến một thư mục khác với thư mục vừa tạo. Chuẩn bị ./ Cho các đường dẫn tương đối sẽ sửa lỗi này (điều này khiến CDPATH bị bỏ qua).
  • Nếu mkdir không thành công, nó sẽ cố thực thi cd. Khắc phục: sử dụng && Để tách hai lệnh.

Vẫn khá đơn giản:

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

Phiên bản này vẫn có khả năng khiến cd đi vào một thư mục khác với thư mục mkdir vừa được tạo trong một trường hợp Edge: nếu đối số thành mkcd chứa .. Và đi qua một liên kết tượng trưng. Ví dụ: nếu thư mục hiện tại là /tmp/heremylink là một liên kết tượng trưng đến /somewhere/else, Thì mkdir mylink/../foo Tạo /somewhere/else/foo Trong khi cd mylink/../foo Thay đổi thành foo. Không đủ để tìm kiếm các liên kết tượng trưng trong đối số, vì Shell cũng theo dõi các liên kết tượng trưng trong thư mục hiện tại của chính nó, vì vậy cd /tmp/mylink; mkdir ../foo; cd ../foo Không thay đổi thành thư mục mới (/somewhere/else/foo) Nhưng thành /tmp/foo. Cách khắc phục cho vấn đề này là để cho cd dựng sẵn giải quyết tất cả các thành phần đường dẫn .. (Sẽ không có ý nghĩa khi sử dụng foo/.. Nếu foo doesn ' T tồn tại, vì vậy mkdir không bao giờ cần xem bất kỳ ..).

Chúng tôi đến với phiên bản mạnh mẽ này nếu hơi 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
}

(Bài tập: tại sao tôi lại sử dụng một mạng con cho cuộc gọi cd đầu tiên?)

Nếu mkdir thất bại, tôi muốn chắc chắn không thay đổi thư mục hiện tại. Thay đổi lại bằng cd - hoặc $ OLDPWD không đủ tốt nếu Shell không có quyền thay đổi vào thư mục hiện tại của nó. Ngoài ra, gọi cd cập nhật OLDPWD, vì vậy chúng tôi chỉ muốn thực hiện một lần (hoặc khôi phục OLDPWD).


Cũng có những cách ít chuyên biệt hơn để không phải gõ lại Word từ dòng trước:

  • Nhập cd, sau đó Esc. (hoặc là Alt+.) để chèn đối số cuối cùng từ lệnh trước đó.
  • cd !$ Thực thi cd trên đối số cuối cùng của lệnh trước đó.
  • Nhấn Up để gọi lại dòng lệnh trước đó, sau đó chỉnh sửa nó để thay đổi mkdir thành cd.
172

Đây là một lớp lót mà bạn cần. Không cần cấu hình khác:

mkdir longtitleproject && cd $_

Các $_ biến, trong bash, là đối số cuối cùng được đưa ra cho lệnh trước đó. Trong trường hợp này, tên của thư mục bạn vừa tạo. Như đã giải thích trong 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.

Sử dụng cd $_ để truy xuất đối số cuối cùng của lệnh trước thay vì cd !$ bởi vì cd !$ đưa ra đối số cuối cùng của lệnh trước đó trong lịch sử Shell:

cd ~/
mkdir folder && cd !$

bạn kết thúc nhà (hoặc ~ /)

cd ~/
mkdir newfolder && cd $_

bạn kết thúc ở newfolder dưới nhà !! (hoặc ~/newfolder)

151
Jesús Carrera

Nó sẽ không bao giờ xảy ra với tôi để kịch bản hành vi này bởi vì tôi nhập vào sau đây trên cơ sở gần một giờ ...

$ mkdir someDirectory<ENTER>
$ cd !$

nơi bash vui lòng thay thế !$ với từ cuối cùng của dòng cuối cùng; tức là tên thư mục dài mà bạn đã nhập.

Ngoài ra, hoàn thành tên tệp là bạn của bạn trong những tình huống như vậy. Nếu thư mục mới của bạn là tệp duy nhất trong thư mục tăng gấp đôi TAB sẽ cung cấp cho bạn thư mục mới mà không cần nhập lại.

Mặc dù thật tuyệt khi bash cho phép bạn tạo ra các tác vụ phổ biến như các câu trả lời khác cho thấy tôi nghĩ tốt hơn là nên tìm hiểu các tính năng chỉnh sửa dòng lệnh mà bash phải cung cấp để khi bạn làm việc trên một máy khác, bạn không bị thiếu cú ​​pháp đường mà tập lệnh tùy chỉnh của bạn cung cấp.

30
Rob

Theo Bạn đã thực hiện những tùy chỉnh nào trong hồ sơ Shell của mình để tăng năng suất? , đây là cách tôi thực hiện:

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

nó có nghĩa là nó cũng hoạt động nếu thư mục đã tồn tại.

17
Mikel

Nếu bạn sử dụng Oh My Zsh, có một lệnh được gọi là mất thực hiện chính xác điều này. Nó sẽ trông giống như thế này.

take myfolder

Tôi thực sự tìm thấy cái này một cách tình cờ. Tôi chỉ nhìn và nó được liệt kê trên chiếc áo này từ wiki Oh My Zsh GitHub. Đó là một lệnh khá hữu ích và dường như rất dễ dàng để tạo ra chính mình.

16
Jordan Harris

Hoặc bạn chỉ có thể tạo một biến ngắn khi đang di chuyển và sử dụng nó hai lần x = longproject ; mkdir $x ; cd $x - mà tôi thừa nhận vẫn còn dài hơn so với sử dụng hàm shellscript :)

3
sakisk

Tôi đã tạo một kịch bản tạo thư mục và sau đó cd vào nó, sau đó tôi đã đặt cho nó một bí danh. Và đây là một Gist nơi tôi mô tả nó.

https://Gist.github.com/rehnen/34236d6ff270ccaa74b6#mkdir-like-it-was-meant-to-be

0
Marcus Rehn

Đây là một biến thể nhỏ đáng được đề cập:

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

Thêm phần này vào ~/.bash_profile Và sau đó bạn có thể sử dụng mkdir như bình thường (một khi bạn đã source 'd nó), ngoại trừ bây giờ nó sẽ chạy chức năng ở trên thay vì lệnh mkdir tiêu chuẩn.

Lưu ý, điều này không xác thực đầu vào theo chấp nhận câu trả lời của Gilles , nhưng chứng minh làm thế nào bạn có thể (có hiệu quả) ghi đè các nội dung.

Từ các tài liệ (diễn giải nhẹ):

command mkdir [args] chạy mkdir với args bỏ qua mọi hàm Shell có tên mkdir. Chỉ các lệnh dựng sẵn Shell hoặc các lệnh được tìm thấy bằng cách tìm kiếm PATH được thực thi. Nếu có hàm Shell có tên ls, việc chạy command ls Trong hàm sẽ thực thi lệnh bên ngoài ls thay vì gọi hàm đệ quy

Tôi tin rằng builtin đạt được kết quả tương tự với command.

0
Arj

Thêm chức năng trợ giúp vào BASH, ZSH hoặc KSH

Tạo lệnh mkcd cho môi trường của bạn trong một dòng

echo -e 'mkcd() {\n mkdir -p "$1" && cd $_\n}' >> ~/.${0//-/}rc && . ~/.${0//-/}rc
0
Proximo