it-swarm-id.com

Apakah ada satu-liner yang memungkinkan saya untuk membuat direktori dan pindah ke sana pada saat yang sama?

Saya mendapati diri saya mengulangi banyak hal:

mkdir longtitleproject
cd longtitleproject

Apakah ada cara melakukannya dalam satu baris tanpa mengulangi nama direktori? Saya bash di sini.

166
methodofaction

Tidak ada perintah bawaan, tetapi Anda dapat dengan mudah menulis fungsi yang memanggil mkdir lalu cd:

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

Masukkan kode ini dalam file ~/.bashrc Anda (atau ~/.kshrc Untuk pengguna ksh, atau ~/.zshrc Untuk pengguna zsh). Ini mendefinisikan fungsi yang disebut mkcd. "$1" Akan digantikan oleh argumen fungsi saat Anda menjalankannya.

Versi sederhana ini memiliki beberapa cacat:

  • Anda tidak dapat membuat rantai subdirektori sekaligus. Perbaiki: lewat opsi -p Ke mkdir. (Ini mungkin atau mungkin tidak diinginkan, karena meningkatkan risiko kesalahan ketik tidak terdeteksi, misalnya mkcd mydierctory/newsub Dengan senang hati akan membuat mydierctory dan mydierctory/newsub Ketika Anda bermaksud membuat newsub di dalam mydirectory yang ada.)
  • Jika argumen dimulai dengan - Tetapi bukan hanya -, Maka mkdir dan cd akan menafsirkannya sebagai opsi. Jika hanya -, Maka cd akan menafsirkannya berarti $OLDPWD. Jika + Diikuti oleh 0 digit atau lebih, maka cd dalam zsh akan menafsirkannya sebagai indeks dalam tumpukan direktori. Anda dapat memperbaiki masalah pertama, tetapi bukan yang kedua, dengan melewati -- Sebelum argumen. Anda dapat memperbaiki semua masalah ini dengan menambahkan ./ Ke argumen jika itu adalah jalur relatif.
  • mkdir tidak mengikuti CDPATH, tetapi cd melakukannya, jadi jika Anda telah menetapkan CDPATH ke nilai yang tidak dimulai dengan . (Konfigurasi yang agak tidak biasa), maka cd dapat membawa Anda ke direktori yang berbeda dari yang baru saja dibuat. Membebani ./ Ke jalur relatif memperbaikinya (ini menyebabkan CDPATH diabaikan).
  • Jika mkdir gagal, ia mencoba mengeksekusi cd. Perbaiki: gunakan && Untuk memisahkan kedua perintah.

Masih cukup sederhana:

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

Versi ini masih memiliki potensi untuk membuat cd masuk ke direktori yang berbeda dari yang mkdir baru saja dibuat dalam satu case Edge: jika argumen ke mkcd berisi .. Dan melewati tautan simbolik. Misalnya, jika direktori saat ini adalah /tmp/here Dan mylink adalah tautan simbolis ke /somewhere/else, Maka mkdir mylink/../foo Menciptakan /somewhere/else/foo Sedangkan cd mylink/../foo Berubah menjadi foo. Tidak cukup untuk mencari tautan simbolik dalam argumen, karena Shell juga melacak tautan simbolik di direktori saat ini, jadi cd /tmp/mylink; mkdir ../foo; cd ../foo Tidak berubah menjadi direktori baru (/somewhere/else/foo) Tetapi ke /tmp/foo. Perbaikan untuk ini adalah membiarkan cd builtin menyelesaikan semua komponen path .. Terlebih dahulu (tidak masuk akal untuk menggunakan foo/.. Jika foo tidak melakukan ' tidak ada, jadi mkdir tidak perlu melihat ..)).

Kami datang ke versi yang kuat jika sedikit berdarah ini:

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
}

(Latihan: mengapa saya menggunakan subkulit untuk panggilan cd pertama?)

Jika mkdir gagal, saya ingin memastikan untuk tidak mengubah direktori saat ini. Mengubah kembali dengan cd - atau $ OLDPWD tidak cukup baik jika Shell tidak memiliki izin untuk berubah ke direktori saat ini. Juga, memanggil cd memperbarui OLDPWD, jadi kami hanya ingin melakukannya sekali (atau mengembalikan OLDPWD).


Ada juga cara yang kurang terspesialisasi untuk tidak perlu mengetik ulang kata dari baris sebelumnya:

  • Ketik cd, lalu Esc. (atau Alt+.) untuk memasukkan argumen terakhir dari perintah sebelumnya.
  • cd !$ Mengeksekusi cd pada argumen terakhir dari perintah sebelumnya.
  • Tekan Up untuk memanggil kembali baris perintah sebelumnya, kemudian edit untuk mengubah mkdir menjadi cd.

Ini adalah satu-liner yang Anda butuhkan. Tidak diperlukan konfigurasi lain:

mkdir longtitleproject && cd $_

$_ variabel, dalam bash, adalah argumen terakhir yang diberikan pada perintah sebelumnya. Dalam hal ini, nama direktori yang baru saja Anda buat. Seperti yang dijelaskan dalam 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.

Gunakan cd $_ untuk mengambil argumen terakhir dari perintah sebelumnya alih-alih cd !$ karena cd !$ memberikan argumen terakhir dari perintah sebelumnya dalam sejarah Shell:

cd ~/
mkdir folder && cd !$

anda berakhir di rumah (atau ~ /)

cd ~/
mkdir newfolder && cd $_

anda berakhir di folder baru di bawah rumah !! (atau ~/folder baru)

151
Jesús Carrera

Tidak pernah terpikir oleh saya untuk memperbaiki perilaku ini karena saya memasukkan yang berikut setiap jam ...

$ mkdir someDirectory<ENTER>
$ cd !$

di mana bash dengan hormat mengganti !$ dengan kata terakhir dari baris terakhir; mis. nama direktori panjang yang Anda masukkan.

Selain itu, penyelesaian nama file adalah teman Anda dalam situasi seperti itu. Jika direktori baru Anda adalah satu-satunya file dalam folder, gandakan cepat TAB akan memberi Anda direktori baru tanpa memasukkannya kembali.

Meskipun keren, bash memungkinkan Anda untuk skrip tugas-tugas umum seperti jawaban lain menyarankan saya pikir lebih baik untuk mempelajari fitur pengeditan baris perintah yang ditawarkan bash sehingga ketika Anda bekerja pada komputer lain Anda tidak kehilangan sintaksisnya gula yang disediakan skrip khusus Anda.

30
Rob

Per Kustomisasi apa yang telah Anda lakukan pada profil Shell Anda untuk meningkatkan produktivitas? , ini adalah bagaimana saya melakukannya:

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

itu berarti juga berfungsi jika direktori sudah ada.

17
Mikel

Jika Anda menggunakan Oh My Zsh, ada perintah yang disebut take yang melakukan hal ini. Akan terlihat seperti ini.

take myfolder

Saya benar-benar menemukan ini secara tidak sengaja. Saya baru saja melihat dan terdaftar di cheatsheat ini dari wiki Oh My Zsh GitHub. Ini perintah yang cukup berguna, dan tampaknya sangat mudah dibuat sendiri.

16
Jordan Harris

Atau Anda bisa membuat variabel pendek sambil jalan dan menggunakannya dua kali x = longproject ; mkdir $x ; cd $x - yang saya akui masih lebih lama daripada menggunakan fungsi shellscript :)

3
sakisk

Saya membuat skrip yang membuat direktori dan kemudian cd untuk itu, lalu saya berikan alias. Dan di sini adalah Intis di mana saya menggambarkannya.

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

0
Marcus Rehn

Berikut adalah sedikit varian yang layak disebutkan:

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

Tambahkan ini ke ~/.bash_profile dan Anda dapat menggunakan mkdir seperti biasa (setelah Anda source 'd itu), kecuali sekarang ia akan menjalankan fungsi di atas daripada perintah standar mkdir .

Catatan, ini tidak memvalidasi input sesuai yang diterima jawaban oleh Gilles , tetapi menunjukkan bagaimana Anda dapat (secara efektif) mengesampingkan builtin.

Dari dokumen (parafrase sedikit):

command mkdir [args] menjalankan mkdir dengan args mengabaikan fungsi Shell yang bernama mkdir. Hanya perintah builtin Shell atau perintah yang ditemukan dengan mencari PATH dieksekusi. Jika ada fungsi Shell bernama ls, menjalankan command ls di dalam fungsi akan menjalankan perintah eksternal ls alih-alih memanggil fungsi secara rekursif

Saya percaya builtin mencapai hasil yang mirip dengan command.

0
Arj

Menambahkan fungsi pembantu ke BASH, ZSH atau KSH

Buat perintah mkcd untuk lingkungan Anda dalam satu baris

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