เป็นไปได้หรือไม่ที่จะแทนที่คำสั่งที่สร้างขึ้นในคำสั่ง“ cd”?


22

ทุกครั้งที่ฉัน 'cd' ไปยังไดเรกทอรีอื่นบนเครื่องของฉัน (ในกรณีนี้ใช้ Mac OS X 10.6.7) ผ่านทางบรรทัดคำสั่ง (ซึ่งเป็น bash) ฉันพิมพ์ 'ls' ทันทีเพื่อรับรายการเนื้อหา ในไดเรกทอรีนั้น ฉันกำลังพยายามหาวิธีแทนที่ 'cd' เพื่อให้มันเปลี่ยนไปยังไดเรกทอรีที่ร้องขอจากนั้นให้รายการในภาพเดียว

ฉันสามารถรับฟังก์ชั่นพื้นฐานที่ฉันกำลังมองหาทำงานโดยเพิ่มบรรทัดต่อไปนี้ลงใน ~ / .bash_profile ของฉัน

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

ทำงานได้ตามที่คาดไว้ เปลี่ยนเป็นไดเร็กทอรีที่ร้องขอจากนั้นแสดงเนื้อหาให้ฉัน ที่ฉันพบปัญหาพยายามแทนที่ "cd" ตัวเองแทนที่จะสร้างคำสั่ง "cl" ใหม่

สิ่งต่อไปนี้ไม่ได้ทำงาน

##### 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;

ฉันยังลองทำซ้ำอีกหลายรายการที่ไม่ได้อยู่ในรายการรวมถึงสร้างนามแฝงที่ชี้ไปที่ฟังก์ชั่น 'cl' ไม่ทำงานเลย

สิ่งที่ฉันได้อ่านในเอกสารอธิบายเกี่ยวกับความจริงที่ว่า 'cd' ไม่สามารถเรียกใช้เป็นคำสั่งภายนอกได้ (ซึ่งเป็นสิ่งที่ฉันเข้าใจว่าเป็นวิธีที่ฟังก์ชั่นจะต้องใช้งาน)

ดังนั้นฉันสามารถใช้คำสั่ง "cl" ของฉันและรับสิ่งที่ต้องการได้ แต่คำถามคือ / ยังคงอยู่:

มีวิธีที่จะแทนที่พฤติกรรมของ 'cd' เพื่อให้มันเปลี่ยนไปยังไดเรกทอรีที่ร้องขอแล้วทำอย่างอื่นหลังจากนั้น?

คำตอบ:


30

ต่อไปนี้ควรทำงาน:

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

เนื่องจากฟังก์ชั่นนั้นอยู่ในบรรทัดเดียวตรวจสอบให้แน่ใจว่ามันถูกยกเลิกด้วย;ดังข้างต้นเพื่อให้ทำงานได้อย่างถูกต้อง


ไม่ทำงานสำหรับการโทรแบบไม่มีพารามิเตอร์
Daniel Beck

3
@DanielBeck - อย่างน้อยใน Mac OSX ของฉัน (10.6.7) มันทำงานได้ดีกับการโทรแบบไม่มีพารามิเตอร์ พฤติกรรมคือมันเปลี่ยนไปที่โฮมไดเร็กตอรี่จากนั้นทำรายการ dir ทำซ้ำฟังก์ชันการทำงานของ 'cd' แบบเก่าอย่างมีประสิทธิภาพด้วยคุณลักษณะใหม่ที่เพิ่มเข้ามาในตอนท้าย
Alan W. Smith

2
@Alan True ฉันทดสอบว่าโดยการเขียนโค้ดเฉพาะกิจลงในเชลล์ ดูเหมือนว่าพฤติกรรมของcd ""(กับสิ่งที่คำตอบนี้ควรประเมินแตกต่างจากที่cd "$@"ว่างเปล่า$@ขออภัยเกี่ยวกับความสับสน
Daniel Beck

@DanielBeck - ไม่ต้องกังวล
Alan W. Smith

2
หมายเหตุ: ฉันเปลี่ยนสิ่งนี้เป็นคำตอบที่ยอมรับเนื่องจากเป็นคำตอบที่แม่นยำสำหรับคำถาม หนึ่งโดย @RichHomolka นั้นยอดเยี่ยมสำหรับการจัดการกับหลักการ แต่อันนี้เป็นสิ่งที่สามารถใส่ในไฟล์ ~ / .bash_profile ของคุณได้
Alan W. Smith

10

ฉันคิดว่าคุณกำลังวิ่งวนซ้ำ cdฟังก์ชั่นของคุณกำลังโทรcdซึ่งเป็น ... ฟังก์ชั่น

คุณจำเป็นต้องรู้ว่าbuiltinคำหลักใดที่ทำให้การค้นหาคำสั่งใช้ Bash builtins เช่น cd และไม่ใช่ฟังก์ชั่นของคุณ

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

การโทร/usr/bin/cdจะไม่ทำงานแม้ว่าจะมีคำสั่งดังกล่าวอยู่ก็ตาม

อะไรจะเกิดขึ้น:

  • ฉันเปลือกทุบตีอยู่ใน /bash/dirdir
  • /usr/bin/cd /dir/for/cdฉันเรียกใช้คำสั่ง
  • /usr/bin/cdไป /dir/for/cddir
  • /usr/bin/cd ทางออก
  • Bash ยังอยู่ใน/bash/dirเนื่องจากกระบวนการลูก/usr/bin/cdไม่สามารถส่งผลกระทบต่อผู้ปกครอง

นามแฝงยังมีการแทนที่ข้อความอย่างง่าย พวกเขาไม่สามารถมีพารามิเตอร์


ผมขอแนะนำbuiltin cd $@ && ls; ตั้งแต่การcdโทรควรประสบความสำเร็จในทุกสิ่งเพื่อให้มีเหตุผล นอกจากนี้ให้จำกรณีพิเศษเช่นcd(ไม่มีอาร์กิวเมนต์)
Daniel Beck

หมายเหตุด้านข้าง: ฉันพยายามทำเครื่องหมายว่าเป็นคำตอบที่ยอมรับ แต่มันบอกฉันว่าฉันต้องรออีก 6 นาทีก่อนที่ฉันจะทำอย่างนั้นได้ ไม่ทราบว่ามีความล่าช้าในตัวก่อนที่คุณจะทำเช่นนั้นได้
Alan W. Smith

@Alan อีกวิธีแก้ปัญหาที่ดีกว่าอาจเกิดขึ้นในกรอบเวลาที่สมเหตุสมผล (นั่นคือไม่กี่นาทีที่คุณต้องรอ) ฉันเดาว่าเป็นเพราะเหตุใดระบบจึงล่าช้า: คุณควรมีคุณภาพมากกว่าความเร็ว ไม่ควรเกินความไม่สะดวก
Daniel Beck

และเรามีผู้ชนะ งานนี้เหมือนแชมป์ ต่อ @DanielBeck ฉันเปลี่ยนไปใช้ && และย่อให้เป็นหนึ่งบรรทัดด้วย: function cd {builtin cd "$ @" && ls -l; }
Alan W. Smith

@DanielBeck - ใช่ฉันไม่กังวลหรอก ไม่เคยสังเกตมาก่อน ฉันเห็นตรรกะในนั้นแค่ทำให้ฉันแปลกใจเล็กน้อย
Alan W. Smith

6

ฉันขอแนะนำไม่ให้แทนที่ cd เพราะมีสคริปต์อื่น ๆ ที่หักหลังฟังก์ชั่น 'cd' ตัวอย่างเช่น rvm จะเป็นการดีกว่าถ้าเลือกชื่ออื่นเช่น 'd' แทนและไม่ระบุประเภท 'builtin' ในฟังก์ชั่นของคุณ มิฉะนั้นนักจี้จะไม่ทำงาน ฉันใช้รหัสด้านล่าง:

function d() { cd "$@" && ls;} 

ฉันคิดว่ามันจะไม่ทำงานแม้ว่าตามคำถามของ OP
user305964
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.