Apakah mungkin untuk menimpa perintah baris yang dibuat dengan perintah "cd"?

22

Hampir setiap kali saya 'cd' ke direktori berbeda di komputer saya (dalam hal ini, menjalankan Mac OS X 10.6.7) melalui baris perintah (yang bash), saya segera mengetik 'ls' untuk mendapatkan daftar isi dalam direktori itu. Saya mencoba mencari cara untuk mengganti 'cd' sehingga itu berubah ke direktori yang diminta dan kemudian memberi saya daftar dalam satu kesempatan.

Saya sudah bisa mendapatkan fungsionalitas dasar yang saya cari bekerja dengan baris berikut ditambahkan ke ~ / .bash_profile saya

function cl() { cd "$@"; ls -l; }

Ini berfungsi seperti yang diharapkan. Mengubah ke direktori yang diminta dan kemudian menunjukkan kepada saya isinya. Di mana saya mengalami masalah sedang mencoba untuk menimpa "cd" itu sendiri alih-alih membuat perintah "cl" baru.

Hal-hal berikut tidak berfungsi

##### Attempt 1 #####
# Hangs the command line

function cd() { cd "$@"; ls -l; }


##### Attempt 2 #####
# Hangs the command line

function cd() { 'cd' "$@"; ls -l; }


##### Attempt 3 #####
# Does not change directory. 
# Does list contents, but of the directory where you started.

function cd() { /usr/bin/cd "$@"; ls -l; }


#### Other attempts that fail in various ways #####
alias cd=cd "$@"; ls -la;
alias cd="cd '$@'; ls -la;"
alias cd='cd "$@"'; ls -la;
alias cd=/usr/bin/cd "$@"; ls -la;

Saya juga mencoba beberapa iterasi lain yang tidak terdaftar serta membuat alias yang menunjuk ke fungsi 'cl' yang berfungsi. Tidak ada yang berhasil.

Apa yang saya baca dalam pembicaraan dokumentasi tentang fakta bahwa 'cd' tidak dapat dijalankan sebagai perintah eksternal (yang saya pahami sebagai cara fungsi perlu menggunakannya).

Jadi, saat ini saya dapat menggunakan perintah "cl" saya dan mendapatkan yang saya inginkan, tetapi pertanyaannya adalah / tetap:

Apakah ada cara untuk mengesampingkan perilaku 'cd' untuk mengubahnya ke direktori yang diminta dan kemudian melakukan hal lain sesudahnya?

Alan W. Smith
sumber

Jawaban:

30

Berikut ini harus bekerja:

function cd() { builtin cd "$@" && ls -l; }

Karena fungsi berada pada satu baris, pastikan fungsi tersebut diakhiri dengan ;seperti di atas agar berfungsi dengan benar.

Taji
sumber
Tidak berfungsi untuk panggilan tanpa parameter.
Daniel Beck
3
@DanielBeck - setidaknya pada Mac OSX saya (10.6.7) ini berfungsi dengan baik dengan panggilan tanpa parameter. Perilaku ini berubah ke direktori home dan kemudian daftar dir itu. Secara efektif menggandakan fungsi 'cd' lama-polos dengan fitur baru yang ditambahkan di bagian akhir.
Alan W. Smith
2
@Lan Benar, saya mengujinya dengan menulis kode ad-hoc ke dalam shell. Tampaknya perilaku cd ""(untuk apa jawaban ini harus mengevaluasi berbeda dari cd "$@"dengan kosong $@. Maaf tentang kebingungan.
Daniel Beck
@DanielBeck - jangan khawatir.
Alan W. Smith
2
Catatan: Saya mengubah ini menjadi jawaban yang diterima karena ini adalah jawaban yang tepat untuk pertanyaan itu. Yang oleh @RichHomolka sangat bagus untuk menangani kepala sekolah, tetapi yang ini bisa dimasukkan ke dalam file ~ / .bash_profile Anda.
Alan W. Smith
10

Saya pikir Anda mengalami loop. cdFungsi Anda memanggil cd, yaitu ... fungsi.

Anda perlu tahu tentang builtinkata kunci mana yang membuat pencarian perintah menggunakan Bash bawaan seperti cd dan bukan fungsi Anda

function cd
{
    builtin cd "$1"
    : do something else
}

Juga, panggilan /usr/bin/cdtidak akan pernah berhasil, bahkan jika perintah seperti itu ada.

Apa yang akan terjadi:

  • Shell Bash saya dalam direktori /bash/dir.
  • Saya menjalankan perintah /usr/bin/cd /dir/for/cd.
  • /usr/bin/cdpergi ke dir /dir/for/cd.
  • /usr/bin/cd keluar.
  • Bash masih dalam /bash/dir, karena proses anak /usr/bin/cdtidak dapat mempengaruhi orang tua.

Alias ​​juga merupakan pengganti teks sederhana. Mereka tidak pernah memiliki parameter.

Homolka yang kaya
sumber
Saya sarankan builtin cd $@ && ls; karena cdpanggilan itu harus berhasil agar semuanya masuk akal. Juga, ingat kasus khusus seperti cd(tidak ada argumen).
Daniel Beck
Catatan Samping: Saya mencoba menandai ini sebagai jawaban yang diterima, tetapi ia mengatakan saya harus menunggu 6 menit lagi sebelum saya bisa melakukannya. Tidak tahu ada penundaan bawaan sebelum Anda bisa melakukannya.
Alan W. Smith
@Lan Lain, solusi yang lebih baik mungkin muncul dalam jangka waktu yang sangat wajar (yaitu beberapa menit Anda harus menunggu). Saya kira itu sebabnya ada penundaan sistem yang diamanatkan: Anda harus lebih memilih kualitas daripada kecepatan. Seharusnya tidak terlalu merepotkan.
Daniel Beck
Dan kami memiliki seorang pemenang. Ini bekerja seperti juara. Per @DanielBeck, saya berubah menggunakan && dan memadatkannya menjadi satu baris dengan: function cd {builtin cd "$ @" && ls -l; }
Alan W. Smith
@DanielBeck - Ya, saya tidak khawatir tentang itu. Hanya tidak pernah menyadarinya sebelumnya. Saya bisa melihat logika di dalamnya, sedikit mengejutkan saya.
Alan W. Smith
6

Saya sarankan untuk tidak menimpa cd karena ada beberapa skrip lain yang membajak fungsi 'cd', misalnya, rvm. Akan lebih baik untuk memilih nama lain, seperti 'd', dan jangan menentukan tipe 'builtin' di fungsi Anda; jika tidak, pembajak tidak akan berfungsi. Saya menggunakan kode di bawah ini:

function d() { cd "$@" && ls;} 
Wen
sumber
Saya pikir ini tidak akan berhasil, sesuai pertanyaan OP.
user305964