ฉันพบว่าตัวเองกำลังทำซ้ำจำนวนมาก:
mkdir longtitleproject
cd longtitleproject
มีวิธีการทำในหนึ่งบรรทัดโดยไม่ต้องทำซ้ำชื่อไดเรกทอรีหรือไม่? ฉันทุบตีที่นี่
mkdir longtitleprojectจากนั้นcd !^
ฉันพบว่าตัวเองกำลังทำซ้ำจำนวนมาก:
mkdir longtitleproject
cd longtitleproject
มีวิธีการทำในหนึ่งบรรทัดโดยไม่ต้องทำซ้ำชื่อไดเรกทอรีหรือไม่? ฉันทุบตีที่นี่
mkdir longtitleprojectจากนั้นcd !^
คำตอบ:
ไม่มีคำสั่งในตัว แต่คุณสามารถเขียนฟังก์ชันที่เรียกใช้mkdirแล้วcd:
mkcd () {
mkdir "$1"
cd "$1"
}
ใส่รหัสนี้ใน~/.bashrcไฟล์ของคุณ(หรือ~/.kshrcสำหรับผู้ใช้ ksh หรือ~/.zshrcสำหรับผู้ใช้ zsh) mkcdมันกำหนดฟังก์ชั่นที่เรียกว่า "$1"จะถูกแทนที่ด้วยอาร์กิวเมนต์ของฟังก์ชั่นเมื่อคุณเรียกใช้
เวอร์ชั่นง่ายนี้มีข้อบกพร่องหลายประการ:
-p mkdir(สิ่งนี้อาจเป็นที่ต้องการหรือไม่ต้องการเนื่องจากเป็นการเพิ่มความเสี่ยงของการพิมพ์ที่ไม่ถูกตรวจจับเช่นmkcd mydierctory/newsubจะสร้างความสุขmydierctoryและmydierctory/newsubเมื่อคุณต้องการสร้างnewsubภายในที่มีอยู่เดิมmydirectory)-แต่ไม่ใช่เพียงแค่-นั้นmkdirและcdจะตีความว่าเป็นตัวเลือก ถ้ามันเป็นเพียง-แล้วจะตีความมันจะหมายถึงcd $OLDPWDหาก+ตามด้วย 0 หรือมากกว่าหลักแล้วcdใน zsh จะตีความว่ามันเป็นดัชนีในไดเรกทอรีสแต็ค คุณสามารถแก้ไขปัญหาแรก แต่ไม่ใช่อีกสองปัญหาได้โดยผ่าน--ก่อนอาร์กิวเมนต์ คุณสามารถแก้ไขปัญหาเหล่านี้ได้โดย./ต่อท้ายอาร์กิวเมนต์ถ้าเป็นเส้นทางที่สัมพันธ์กันmkdirไม่ปฏิบัติตามCDPATHแต่cdทำเช่นนั้นดังนั้นหากคุณตั้งค่าCDPATHเป็นค่าที่ไม่ได้ขึ้นต้นด้วย.(การกำหนดค่าที่ค่อนข้างผิดปกติ) คุณcdอาจนำคุณไปยังไดเรกทอรีอื่นที่ไม่ใช่ที่เพิ่งสร้างขึ้น prepending ./เส้นทางญาติแก้ไขนี้ (มันเป็นสาเหตุCDPATHที่จะละเลย)mkdir cdคงที่: ใช้&&เพื่อแยกทั้งสองคำสั่งยังค่อนข้างง่าย:
mkcd () {
case "$1" in /*) :;; *) set -- "./$1";; esac
mkdir -p "$1" && cd "$1"
}
รุ่นนี้ยังคงมีศักยภาพที่จะทำให้cdเป็นไดเรกทอรีที่แตกต่างจากที่mkdirเพิ่งสร้างขึ้นในกรณีที่ขอบ: ถ้าอาร์กิวเมนต์ที่จะmkcdมี..และผ่านการเชื่อมโยงสัญลักษณ์ ตัวอย่างเช่นถ้าไดเรกทอรีปัจจุบัน/tmp/hereและmylinkการเชื่อมโยงสัญลักษณ์ไป/somewhere/elseแล้วmkdir mylink/../fooสร้าง/somewhere/else/fooในขณะที่การเปลี่ยนแปลงลงcd mylink/../foo fooมันไม่เพียงพอที่จะมองหาการเชื่อมโยงสัญลักษณ์ในการโต้เถียงเพราะเปลือกยังติดตามการเชื่อมโยงสัญลักษณ์ในไดเรกทอรีปัจจุบันของตัวเองเพื่อcd /tmp/mylink; mkdir ../foo; cd ../fooไม่เปลี่ยนแปลงลงในไดเรกทอรีใหม่ ( /somewhere/else/foo) /tmp/fooแต่ลงไปใน การแก้ไขสำหรับสิ่งนี้คือเพื่อให้cdbuiltin แก้ไข..คอมโพเนนต์พา ธทั้งหมดก่อน (ไม่ควรใช้foo/..หากfooไม่มีอยู่ดังนั้นmkdirไม่จำเป็นต้องเห็นเลย..)
เรามาถึงเรื่องนี้หากเวอร์ชั่นเต็มไปด้วยเลือดเล็กน้อย:
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
}
(การออกกำลังกาย: ทำไมฉันถึงใช้ subshell สำหรับการcdโทรครั้งแรก?)
หาก mkdir ล้มเหลวฉันต้องการแน่ใจว่าจะไม่เปลี่ยนไดเรกทอรีปัจจุบัน เปลี่ยนกลับด้วย cd - หรือ $ OLDPWD ไม่ดีพอถ้าเชลล์ไม่ได้รับอนุญาตให้เปลี่ยนเป็นไดเรกทอรีปัจจุบัน นอกจากนี้การเรียกการอัปเดตซีดี OLDPWD ดังนั้นเราจึงต้องการทำเพียงครั้งเดียว (หรือกู้คืน OLDPWD)
นอกจากนี้ยังมีวิธีที่เชี่ยวชาญน้อยกว่าโดยไม่ต้องพิมพ์คำซ้ำจากบรรทัดก่อนหน้า:
cd แล้วEsc .(หรือAlt+ .) เพื่อแทรกอาร์กิวเมนต์ล่าสุดจากคำสั่งก่อนหน้าcd !$รันcdบนอาร์กิวเมนต์สุดท้ายของคำสั่งก่อนหน้าmkdircdkshและยังทำงานได้zsh) สำหรับ "ทำซ้ำคำสุดท้ายของคำสั่งก่อนหน้า" ฉันใช้มันค่อนข้างบ่อย
/a/b/..//จริงจะทำงานได้ /a/b/../cแต่ไม่ได้ แก้ไขแล้ว. ฉันตั้งคำถามให้กับผู้ชมที่กว้างขึ้น
mkcd() { mkdir -p "$1" && cd "$1"; }ดูเหมือนจะไม่เป็นปัญหาใน (ตัวอย่างของฉัน) zsh mkdir -p /var/tmp/somewhere/else /tmp/here; cd /tmp/here; ln -s /var/tmp/somewhere/else mylink; mkdir -p mylink/../foo && cd mylink/../foo; pwd(รวมถึงการตั้งค่าและ) แสดง/tmp/here/fooสิ่งที่ถูกสร้างขึ้น (และสิ่งที่ฉันคาดไว้) bashสร้างและเปลี่ยนแปลง/var/tmp/somewhere/fooอย่างไม่เหมาะสม
นี่คือหนึ่งซับที่คุณต้องการ ไม่ต้องการการกำหนดค่าอื่น ๆ :
mkdir longtitleproject && cd $_
$_ตัวแปรในทุบตีเป็นอาร์กิวเมนต์สุดท้ายที่กำหนดให้คำสั่งก่อนหน้า ในกรณีนี้ชื่อของไดเรกทอรีที่คุณเพิ่งสร้างขึ้น ตามที่อธิบายไว้ใน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.
ใช้cd $_เพื่อดึงอาร์กิวเมนต์สุดท้ายของคำสั่งก่อนหน้านี้แทนcd !$เพราะcd !$ให้อาร์กิวเมนต์สุดท้ายของคำสั่งก่อนหน้าในประวัติเชลล์ :
cd ~/
mkdir folder && cd !$
คุณท้ายบ้าน (หรือ ~ /)
cd ~/
mkdir newfolder && cd $_
คุณจบลงที่โฟลเดอร์ใหม่ภายใต้บ้าน !! (หรือ ~ / โฟลเดอร์ใหม่)
mkdir foo && cd fooซึ่งไม่สะดวก
มันจะไม่เกิดขึ้นกับฉันที่จะเขียนสคริปต์พฤติกรรมนี้เพราะฉันป้อนต่อไปนี้ในเกือบชั่วโมง ...
$ mkdir someDirectory<ENTER>
$ cd !$
โดยที่ bash กรุณาแทนที่!$ด้วยคำสุดท้ายของบรรทัดสุดท้าย; คือชื่อไดเรกทอรีแบบยาวที่คุณป้อน
นอกจากนี้การเติมชื่อไฟล์ให้เพื่อนของคุณในสถานการณ์เช่นนี้คือ หากไดเรกทอรีใหม่ของคุณเป็นไฟล์เดียวในโฟลเดอร์ double อย่างรวดเร็วTABจะให้ไดเรกทอรีใหม่โดยไม่ต้องป้อนซ้ำ
แม้ว่ามันจะเจ๋งมากที่ bash ช่วยให้คุณสามารถสคริปต์งานทั่วไปเช่นคำตอบอื่น ๆ ขอแนะนำฉันคิดว่ามันจะดีกว่าที่จะเรียนรู้คุณสมบัติการแก้ไขบรรทัดคำสั่งที่ bash มีให้เพื่อที่ว่าเมื่อคุณทำงานกับเครื่องอื่น น้ำตาลที่สคริปต์ของคุณกำหนดเอง
ตามที่คุณได้ทำการปรับแต่งในโปรไฟล์ shell เพื่อเพิ่มประสิทธิภาพ? นี่คือวิธีที่ฉันทำ:
# make a directory and cd to it
mcd()
{
test -d "$1" || mkdir "$1" && cd "$1"
}
มันหมายความว่ายังใช้งานได้หากไดเรกทอรีมีอยู่แล้ว
-pตัวเลือกในการ mkdir จะยกเลิกข้อผิดพลาด
mcdคำสั่งที่มีอยู่คืออะไร? แพคเกจหรือโครงการใดให้คำสั่งนี้
ถ้าคุณใช้ Oh My zsh มีคำสั่งเรียกใช้ที่ไม่ตรงนี้ มันจะมีลักษณะเช่นนี้
take myfolder
ฉันเจออันนี้โดยบังเอิญ ฉันเพิ่งดูและมันถูกระบุไว้ในสูตรโกงนี้จากวิกิโอ้ Oh My Zsh GitHub มันค่อนข้างจะเป็นคำสั่งที่มีประโยชน์และดูเหมือนจะสร้างตัวเองได้ง่ายมาก
take:) สมบูรณ์แบบ! btw - iTerm2 กับ Oh My Zsh จริงๆแล้วมี 3 คำตอบที่สมบูรณ์แบบที่นี่ อันนี้อันนี้โดย @ jesús-carrera และคำตอบที่เลือก ขึ้นอยู่กับการตั้งค่าและการตั้งค่าของคุณ
หรือคุณเพียงแค่สร้างตัวแปรสั้น ๆ แบบทันทีและใช้มันสองครั้งx = longproject ; mkdir $x ; cd $x- ซึ่งฉันยอมรับว่ายังใช้งานได้นานกว่าการใช้ฟังก์ชัน shellscript :)
นี่คือตัวแปรที่ควรพูดถึง:
function mkdir() {
local dir=$1
command mkdir "$dir" && cd "$dir"
}
เพิ่มสิ่งนี้ลงในของ~/.bash_profileคุณแล้วคุณสามารถใช้งานได้mkdirตามปกติ (เมื่อคุณใช้งานแล้วsource) ยกเว้นตอนนี้มันจะเรียกใช้ฟังก์ชันด้านบนแทนmkdirคำสั่งมาตรฐาน
หมายเหตุสิ่งนี้ไม่ได้ตรวจสอบความถูกต้องของอินพุตตามคำตอบที่ยอมรับโดย Gillesแต่แสดงให้เห็นว่าคุณสามารถแทนที่ builtins ได้อย่างไร (อย่างมีประสิทธิภาพ)
จากเอกสาร (การถอดความเล็กน้อย):
command mkdir [args]ทำงานmkdirกับไม่สนใจฟังก์ชั่นเชลล์ชื่อargsmkdirคำสั่ง shell builtin เท่านั้นหรือคำสั่งที่พบโดยการค้นหา PATH จะถูกดำเนินการ หากมีชื่อฟังก์ชั่นของเชลล์การlsเรียกใช้command lsภายในฟังก์ชั่นจะดำเนินการคำสั่งภายนอกlsแทนการเรียกใช้ฟังก์ชันซ้ำ
ผมเชื่อว่าประสบความสำเร็จในผลคล้ายกับbuiltincommand
$dir
commandเป็นทางเลือก
สร้างmkcdคำสั่งให้กับสภาพแวดล้อมของคุณในหนึ่งบรรทัด
echo -e 'mkcd() {\n mkdir -p "$1" && cd $_\n}' >> ~/.${0//-/}rc && . ~/.${0//-/}rc
ฉันสร้างสคริปต์ที่สร้างไดเรกทอรีและซีดีของมันจากนั้นฉันให้นามแฝง และนี่คือส่วนสำคัญที่ฉันอธิบายมัน
https://gist.github.com/rehnen/34236d6ff270ccaa74b6#mkdir-like-it-was-meant-to-be
เพียงแค่ตอบคำถามข้างต้นโดยอัตโนมัติและสร้างสคริปต์ที่ใช้งานได้หนึ่งครั้ง:
fun='
mkcd ()
{
mkdir -p -- "$1" && cd -P -- "$1"
}'
echo "$fun" >> ~/.bashrc
เพียงคัดลอกในไฟล์ใหม่mkcd.shและเรียกใช้เพียงครั้งเดียวใน terminal bash mkcd.shโดย จากนั้นดำเนินการsource ~/.bashrcเพื่อให้ทำงานในเซสชันปัจจุบัน
หลังจากนี้คุณสามารถใช้mkcd some_dirเพื่อสร้างและป้อนโดยตรงในไดเรกทอรีนั้น
~/.bashrcไฟล์ (โดยมีคำตอบที่ได้รับไปแล้ว)? และคุณแนะนำให้สร้างmkcd.shสคริปต์นี้อย่างไร ด้วยเครื่องมือแก้ไขอาจ? ~/.bashrcนี้ดูเหมือนว่าการทำงานมากขึ้นกว่าเพียงแค่การแก้ไข สิ่งนี้มีประโยชน์อะไรมากกว่าคำตอบที่ยอมรับได้? …………………………………………………ทุก…………………………………ทุก ๆ สิ่งนี้จะล้มเหลวเนื่องจากปัญหาในการอ้างอิงซึ่งบอกได้ว่าคุณยังไม่ได้ลองด้วยตัวเอง
mcdจากunix.stackexchange.com/questions/6628/…