ฉันพบว่าตัวเองกำลังทำซ้ำจำนวนมาก:
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
แต่ลงไปใน การแก้ไขสำหรับสิ่งนี้คือเพื่อให้cd
builtin แก้ไข..
คอมโพเนนต์พา ธทั้งหมดก่อน (ไม่ควรใช้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
บนอาร์กิวเมนต์สุดท้ายของคำสั่งก่อนหน้าmkdir
cd
ksh
และยังทำงานได้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
กับไม่สนใจฟังก์ชั่นเชลล์ชื่อargs
mkdir
คำสั่ง shell builtin เท่านั้นหรือคำสั่งที่พบโดยการค้นหา PATH จะถูกดำเนินการ หากมีชื่อฟังก์ชั่นของเชลล์การls
เรียกใช้command ls
ภายในฟังก์ชั่นจะดำเนินการคำสั่งภายนอกls
แทนการเรียกใช้ฟังก์ชันซ้ำ
ผมเชื่อว่าประสบความสำเร็จในผลคล้ายกับbuiltin
command
$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/…