ทำไม“ cd” ไม่ทำงานในเชลล์สคริปต์


766

ฉันกำลังพยายามเขียนสคริปต์ขนาดเล็กเพื่อเปลี่ยนไดเรกทอรีปัจจุบันเป็นไดเรกทอรีโครงการของฉัน:

#!/bin/bash
cd /home/tree/projects/java

ฉันบันทึกแฟ้มนี้เป็น Proj เพิ่มผู้ได้รับอนุญาตมีและคัดลอกไปยังchmod /usr/binเมื่อฉันเรียกมันโดย: projมันไม่ทำอะไรเลย ผมทำอะไรผิดหรือเปล่า?


10
ข้ามไซต์ซ้ำกัน: superuser.com/questions/176783/…
lesmana

ในอนาคตคุณสามารถลองทดสอบด้วยpwdบรรทัดสุดท้าย ดังนั้นก่อนที่สคริปต์จะเสร็จสิ้นคุณสามารถตรวจสอบได้ว่ามันใช้งานได้หรือไม่ ..
sobi3ch

5
@lesmana เป็นวิธีการที่ซ้ำกันอย่างไร
aland

@aland เนื่องจาก OP ไม่ได้เรียกใช้สคริปต์ในความเป็นจริงนั่นคือเหตุผลที่ทำไม dir ที่ทำงานไม่ได้เปลี่ยนให้เขา cdคำสั่งทำงานได้ดีภายในสคริปต์ลองด้วยตัวคุณเอง
Alexander Gonchiy

คำตอบ:


634

เชลล์สคริปต์จะทำงานภายใน subshell และแต่ละ subshell มีคอนเซปต์ของตัวเองว่าไดเรกทอรีปัจจุบันคืออะไร cdประสบความสำเร็จ แต่ทันทีที่ออกจาก subshell คุณกลับมาอยู่ในเปลือกโต้ตอบและไม่เคยมีอะไรเปลี่ยนแปลงมี

วิธีหนึ่งในการหลีกเลี่ยงปัญหานี้คือใช้นามแฝงแทน:

alias proj="cd /home/tree/projects/java"

7
ชื่อแทนไม่ยืดหยุ่นในการจัดการหรือเปลี่ยนแปลง ในกรณีที่ซีดีหลาย ๆ ชุดสคริปต์อาจดีกว่า
Thevs

16
ฟังก์ชั่นมีความยืดหยุ่นมากกว่านามแฝงดังนั้นคุณจะต้องมองหาสิ่งต่อไปเมื่อชื่อแทนไม่เพียงพอ
ephemient

4
เป็นที่น่าสังเกตว่าใน MS-DOS พฤติกรรมของสคริปต์คือสคริปต์ที่เรียกว่าสามารถเปลี่ยนไดเรกทอรี (และแม้กระทั่งไดรฟ์) ของเชลล์คำสั่งการโทรได้หรือไม่ และ Unix นั้นไม่มีข้อบกพร่องนี้หรือไม่?
Jonathan Leffler

23
Jonathan: ในขณะที่เป็นจริงมันไม่ได้เกี่ยวข้องกับคำถาม คำตอบเกี่ยวกับ SO จะได้รับสองครั้งหากพวกเขาแต่ละรายการมีข้อบกพร่องที่สอดคล้องกันใน MS-DOS!
เกร็กฮิวกิลล์

17
วิธีการรับรอบมันก็คือแหล่งไฟล์สคริปต์: หรือ. my-script source my-script
HelloGoodbye

503

คุณไม่ได้ทำอะไรผิด! คุณเปลี่ยนไดเรกทอรี แต่ใช้งานภายใน subshell ที่เรียกใช้สคริปต์เท่านั้น

คุณสามารถเรียกใช้สคริปต์ในกระบวนการปัจจุบันของคุณด้วยคำสั่ง "dot":

. proj

แต่ฉันต้องการคำแนะนำของ Greg เพื่อใช้นามแฝงในกรณีง่าย ๆ นี้


95
.ยังสะกดsourceให้เลือกว่าคุณจะจำอะไรได้มากกว่านี้
ephemient

47
@Ephemient: แหล่งข้อมูลที่ดีที่อธิบายว่าทำไมมันจึงทำงานได้แหล่งข้อมูลพิสูจน์ให้เห็นว่าความเกียจคร้าน - ไม่จำเป็น - มักจะเป็นแหล่งกำเนิดของแหล่งประดิษฐ์
Adam Liss

8
@ephemient: โปรดทราบว่ามีการใช้แหล่งที่มาใน C เชลล์และ Bash ไม่รองรับ POSIX หรือ Korn shell หรือใน Bourne shell แบบคลาสสิก
Jonathan Leffler

2
"source" ใช้ใน Z-shell
Nathan Moos

1
@AdamLiss มันใช้งานได้ดี แต่มีข้อเสียเปรียบอย่างหนึ่ง - คำสั่ง source / dot ปิดใช้งานความเป็นไปได้ที่จะตั้งชื่อสคริปต์ / คำสั่งโดยอัตโนมัติด้วยปุ่ม TAB ยังคงเป็นไปได้ที่จะเพิ่มอาร์กิวเมนต์ / อินพุตด้วยคีย์ TAB แต่น่าเสียดายที่ชื่อของคำสั่งนั้นจำเป็นต้องป้อนข้อมูลโดยตรง คุณรู้วิธีทำให้คีย์ TAB ทำงานในกรณีนี้หรือไม่?
Rafal

215

เทคนิคcdในสคริปต์ของคุณทำงานในขณะที่มันเปลี่ยนไดเรกทอรีของเชลล์ที่รันสคริปต์ แต่นั่นเป็นกระบวนการแยกต่างหากจากเชลล์เชิงโต้ตอบของคุณ

วิธี Posix เข้ากันได้กับการแก้ปัญหานี้คือการกำหนดขั้นตอนเปลือกมากกว่าเปลือกอุทธรณ์คำสั่งสคริปต์

jhome () {
  cd /home/tree/projects/java
}

คุณสามารถพิมพ์สิ่งนี้ในหรือวางไว้ในหนึ่งในไฟล์เริ่มต้นเชลล์ต่างๆ


6
ฉันเห็นด้วยนี่คือคำตอบที่ดีที่สุดชน นอกจากนี้นามแฝงอาจเหมาะสมในบางสถานการณ์ แต่ถ้าเขาพยายามใช้ cd ในสคริปต์และต้องการเพิ่มสิ่งอื่นลงไปนามแฝงจะไร้ประโยชน์
Justin Buser

4
ดูเหมือนว่าวิธีการแก้ปัญหา! และฉันกำลังพยายามที่จะใช้งาน แต่มันไม่ทำงาน :( นี่คือสคริปต์ของฉัน: #! / bin / bash jhome () {echo "โปรด" cd / home echo "work"} jhome
Gant Laborde

1
@GantMan คุณควรเพิ่มสิ่งนี้ใน "shell startup files" เช่น ~ / .bashrc
Jackie Yeh

3
คุณสามารถใช้การโต้แย้ง (หรือสอง ... ) เช่น:jhome(){ cd /home/tree/projects/$1; }
irbanana

1
นี่ควรเป็นวิธีที่ถูกต้องทำให้สามารถใช้อักขระพิเศษเช่น "-" ได้
bangkokguy

159

cdจะทำภายในเปลือกสคริปต์ เมื่อสคริปต์สิ้นสุดลงเชลล์นั้นจะออกจากนั้นคุณจะอยู่ในไดเรกทอรีที่คุณอยู่ สคริปต์ "Source" ไม่ได้เรียกใช้ แทน:

./myscript.sh

ทำ

. ./myscript.sh

(สังเกตเห็นจุดและช่องว่างหน้าชื่อสคริปต์)


2
นี่เจ๋งและน่าจะรู้ สิ่งหลังทำอะไรกันแน่ (มันทำงานยังไง)? นี่อาจเป็นทางออกที่ดีที่สุดในหัวข้อนี้
Jonah

2
fwiw ในส่วนความเห็นของคำตอบของอดัมลิสผู้ที่ตอบกลับมาก็ตอบคำถามว่าอะไร ' คือ. มันเป็นเช่นเดียวกับsource
g19fanatic

1
ระวัง "แหล่งที่มา" คือการทุบตี ie dash (ค่าเริ่มต้น Debian สำหรับ / bin / sh) ไม่รองรับในขณะที่ "." ทำงานตามที่คาดไว้
อัลโล

คำตอบที่ดี! หากmyscript.shอยู่ในไดเรกทอรีที่รวมอยู่ใน $ PATH คุณสามารถหาแหล่งข้อมูลได้จากทุกที่โดยไม่ต้องระบุเส้นทางแบบเต็ม
CodeBrew

สิ่งนี้ได้ผลดีที่สุดสำหรับฉัน วิธีนี้เป็นวิธีที่ง่ายที่สุด (+1)
HuserB1989

96

ในการสร้าง bash script ที่จะ cd ไปยังไดเรกทอรีที่เลือก:

สร้างไฟล์สคริปต์

#! / bin / ดวลจุดโทษ
# file: / สคริปต์ / cdjava
#
cd / home / askgelal / projects / java

จากนั้นสร้างนามแฝงในไฟล์เริ่มต้นของคุณ

#! / bin / ดวลจุดโทษ
# file /scripts/mastercode.sh
#
นามแฝง cdjava = ' / scripts / cdjava'

  • ฉันสร้างไฟล์เริ่มต้นที่ฉันทิ้งชื่อแทนและฟังก์ชั่นที่กำหนดเองทั้งหมดของฉัน
  • จากนั้นฉันก็ใส่ไฟล์นี้ลงใน. bashrc ของฉันเพื่อตั้งค่าไว้ในการบู๊ตแต่ละครั้ง

ตัวอย่างเช่นสร้างไฟล์ aliases / function ต้นแบบ: /scripts/mastercode.sh
(ใส่ alias ในไฟล์นี้)

จากนั้นในตอนท้ายของไฟล์. bashrcของคุณ:

source /scripts/mastercode.sh



ตอนนี้มันง่ายที่จะ cd ไปยังไดเรกทอรี java ของคุณเพียงแค่พิมพ์ cdjava และคุณอยู่ที่นั่น


2
ไฟล์mastercode.shไม่ต้องการ shabang ( #!/bin/sh) เนื่องจากมันไม่ได้ (และไม่สามารถ) ดำเนินการใน subshell แต่ในเวลาเดียวกันคุณจำเป็นต้องจัดทำเอกสารเปลือก "รส" ของไฟล์นี้; เช่น ksh หรือทุบตี (หรือ (t) csh / zsh ฯลฯ ) shและก็เกือบจะแน่นอนไม่จริง ฉันมักจะเพิ่มความคิดเห็น (แต่ไม่ใช่ Shebang) เพื่อสื่อสารสิ่งนี้ เช่น"ไฟล์นี้มีวัตถุประสงค์เพื่อให้ได้มา (จาก bash) ไม่ได้เรียกใช้เป็นเชลล์สคริปต์"
ไมเคิล

เคล็ดลับอื่น (สำหรับการทุบตี): หากคุณใช้ตัวแปรในสคริปต์ของคุณดังนั้นเมื่อสคริปต์กำลังเป็นsourced (ผ่านทางalias) ตัวแปรเหล่านั้นจะรั่วไหลลงสู่สภาพแวดล้อมเชลล์ของคุณ เพื่อหลีกเลี่ยงปัญหานี้ให้ทำงานทั้งหมดของสคริปต์ในฟังก์ชั่นและเรียกมันว่าท้ายสคริปต์ localภายในฟังก์ชั่นการประกาศตัวแปรใด ๆ
Rhubbarb

ใน ubuntu เพียงแค่สร้าง ~ / .bash_aliases (หากยังไม่มีอยู่) จากนั้นเพิ่มนามแฝงของคุณที่นั่นรีสตาร์ทเทอร์มินัลและของคุณเสร็จแล้ว
Vlad

51

คุณสามารถใช้.เพื่อรันสคริปต์ในสภาวะแวดล้อมเชลล์ปัจจุบัน:

. script_name

หรืออีกทางเลือกหนึ่งที่สามารถอ่านได้มากขึ้น แต่เปลือกที่เฉพาะเจาะจงของนามแฝงsource:

source script_name

สิ่งนี้จะหลีกเลี่ยงcdเชลล์ย่อยและอนุญาตให้ตัวแปรหรือบิวด์อิน (รวมถึง) ใด ๆมีผลกับเชลล์ปัจจุบันแทน


38

ความคิดของ Jeremy Ruten ในการใช้ symlink ทำให้เกิดความคิดที่ไม่ได้ข้ามคำตอบอื่น ๆ ใช้:

CDPATH=:$HOME/projects

ลำไส้ใหญ่ชั้นนำมีความสำคัญ หมายความว่าหากมีไดเรกทอรี 'dir' ในไดเรกทอรีปัจจุบันแล้ว ' cd dir' จะเปลี่ยนเป็นดังกล่าวแทนที่จะเปลี่ยนไปที่อื่น ด้วยการตั้งค่าตามที่แสดงคุณสามารถทำ:

cd java

และหากไม่มีไดเรกทอรีย่อยชื่อ java ในไดเรกทอรีปัจจุบันจะนำคุณไปยัง $ HOME / projects / java โดยตรง - ไม่มีนามแฝงไม่มีสคริปต์ไม่มีคำสั่ง execs หรือ dot ที่น่าสงสัย

$ HOME ของฉันคือ / Users / jleffler; $ CDPATH ของฉันคือ:

:/Users/jleffler:/Users/jleffler/mail:/Users/jleffler/src:/Users/jleffler/src/perl:/Users/jleffler/src/sqltools:/Users/jleffler/lib:/Users/jleffler/doc:/Users/jleffler/work

30

ใช้exec bashในตอนท้าย

สคริปต์ทุบตีทำงานในสภาพแวดล้อมปัจจุบันหรือกับลูก ๆ ของมัน แต่ไม่เคยอยู่ในสภาพแวดล้อมหลัก

อย่างไรก็ตามคำถามนี้มักจะถูกถามเพราะต้องการทิ้งไว้ที่พรอมต์ทุบตี (ใหม่) ในไดเรกทอรีหนึ่งหลังจากเรียกใช้สคริปต์ทุบตีจากไดเรกทอรีอื่น

หากเป็นกรณีนี้ให้เรียกใช้งานอินสแตนซ์ bash ย่อยที่ส่วนท้ายของสคริปต์:

#!/usr/bin/env bash
cd /home/tree/projects/java
exec bash

16
สิ่งนี้จะสร้าง subshell ใหม่ เมื่อคุณพิมพ์exitคุณจะกลับสู่เชลล์ที่คุณใช้งานสคริปต์นี้
tripleee

1
เมื่อสคริปต์ถูกเรียกหลายครั้งดูเหมือนว่ามันจะสร้างเชลล์ที่ซ้อนกันและฉันต้องพิมพ์ 'exit' หลายครั้ง สิ่งนี้จะแก้ไขได้ไหม?
VladSavitsky

ดูคำตอบอื่น ๆ : ใช้นามแฝงใช้ "pushd / popd / dirs" หรือใช้ "source"
qneill

25

ฉันได้รหัสของฉันไปใช้งานโดยใช้. <your file name>

./<your file name> โดสไม่ทำงานเพราะมันไม่เปลี่ยนไดเรกทอรีของคุณในเทอร์มินัลเพียงแค่เปลี่ยนไดเรกทอรีเฉพาะของสคริปต์นั้น

นี่คือโปรแกรมของฉัน

#!/bin/bash 
echo "Taking you to eclipse's workspace."
cd /Developer/Java/workspace

นี่คือสถานีของฉัน

nova:~ Kael$ 
nova:~ Kael$ . workspace.sh
Taking you to eclipe's workspace.
nova:workspace Kael$ 

2
ความแตกต่างระหว่าง. somethingและคืออะไร./something? คำตอบนี้ใช้ได้สำหรับฉันและฉันไม่เข้าใจว่าทำไม
Dracorat

. somethingอนุญาตให้คุณเรียกใช้สคริปต์จากตำแหน่งใด ๆ./somethingคุณต้องอยู่ในไดเรกทอรีที่เก็บไฟล์ไว้
Projjol


คุณสามารถใส่จุดลงในบรรทัด Shebang ได้หรือไม่? #!. /bin/bash?
Sigfried


12

เมื่อคุณเรียกใช้เชลล์สคริปต์มันจะเรียกใช้ อินสแตนซ์ใหม่ของเชลล์นั้น ( /bin/bash) ดังนั้นสคริปต์ของคุณเพียงแค่ยิงเชลล์เปลี่ยนไดเรกทอรีและออก ใส่อีกวิธีหนึ่งcd(และคำสั่งอื่น ๆ ) ภายในเชลล์สคริปต์จะไม่ส่งผลกระทบและไม่สามารถเข้าถึงเชลล์ที่ถูกเรียกใช้


11

ในกรณีของฉันโดยเฉพาะฉันต้องเปลี่ยนหลายครั้งเกินไปสำหรับไดเรกทอรีเดียวกัน ดังนั้นใน. bashrc ของฉัน (ฉันใช้ Ubuntu) ฉันได้เพิ่ม

1 -

$ nano ~. / bashrc

 function switchp
 {
    cd /home/tree/projects/$1
 }

2-

$ source ~ / .bashrc

3 -

$ switchp java

โดยตรงจะทำ: cd / home / tree / projects / java

หวังว่าจะช่วย!


1
@WM ในที่สุดคุณสามารถทำ "$ switchp" โดยไม่มีพารามิเตอร์ใด ๆ เพื่อไปยัง
แผนผัง

2
@workdreamer วิธีการใช้งานที่คุณอธิบายไว้ข้างต้นแก้ไขปัญหาเล็กน้อยที่นี่ในการเข้าไปในโฟลเดอร์ย่อยที่มีโฟลเดอร์พาเรนต์เดียวกันกับระบบของฉัน ขอบคุณ.
WM

10

คุณสามารถทำสิ่งต่อไปนี้:

#!/bin/bash
cd /your/project/directory
# start another shell and replacing the current
exec /bin/bash

แก้ไข: นี่อาจเป็น 'ประ' เช่นกันเพื่อป้องกันการสร้างเปลือกหอยที่ตามมา

ตัวอย่าง:

. ./previous_script  (with or without the first line)

1
ที่ค่อนข้างยุ่งหลังจากวิ่งไม่กี่ครั้ง .. คุณจะต้องexit(หรือ ctrl + d) หลายครั้งเพื่อออกจากเชลล์เช่น .. นามแฝงนั้นสะอาดกว่ามาก (แม้ว่าคำสั่งเชลล์จะแสดงไดเรกทอรีและมันเป็นซีดี ไปยังเอาต์พุต - alias something = "cd getnewdirectory.sh")
dbr

หมายเหตุ 'exec' มันทำให้แทนที่ของเปลือกเก่า
Thevs

2
exec จะแทนที่ sub-shell ที่รันคำสั่ง cd เท่านั้นไม่ใช่เชลล์ที่รันสคริปต์ ถ้าคุณจดสคริปต์ไว้คุณก็จะแก้ไขให้ถูกต้อง
Jonathan Leffler

ทำให้เป็น 'จุด' - ไม่มีปัญหา ฉันเพิ่งเสนอวิธีแก้ปัญหา ไม่ได้ขึ้นอยู่กับวิธีที่คุณเปิดตัว
Thevs

2
Hehe ฉันคิดว่ามันจะดีกว่าเพียงแค่ 'dot' สคริปต์บรรทัดเดียวด้วยคำสั่ง cd เท่านั้น :) ฉันจะเก็บคำตอบของฉันต่อไป ... นั่นจะเป็นคำตอบที่โง่ที่ถูกต้องสำหรับคำถามโง่ที่ไม่ถูกต้อง :)
Thevs

7

มันเปลี่ยนไดเรกทอรีสำหรับสคริปต์เท่านั้นในขณะที่ไดเรกทอรีปัจจุบันของคุณยังคงเหมือนเดิม

คุณอาจต้องการใช้ลิงก์สัญลักษณ์แทน จะช่วยให้คุณที่จะทำให้ "ทางลัด" cd my-projectเพื่อแฟ้มหรือไดเรกทอรีดังนั้นคุณจะมีเพียงพิมพ์สิ่งที่ต้องการ


การมี symlink นั้นในทุกไดเรกทอรีจะเป็นสิ่งที่สร้างความรำคาญ เป็นไปได้ที่จะวาง symlink ใน $ HOME จากนั้นทำ 'cd ~ / my-project' อย่างไรก็ตามตรงไปตรงมามันง่ายกว่าที่จะใช้ CDPATH
Jonathan Leffler

7

คุณสามารถรวมนามแฝงของ Adam & Greg เข้าด้วยกันกับแนวทางแบบจุดเพื่อสร้างบางสิ่งที่สามารถมีพลังมากขึ้น -

alias project=". project"

ตอนนี้การเรียกใช้นามแฝงโครงการจะดำเนินการสคริปต์โครงการในเชลล์ปัจจุบันตรงข้ามกับเชลล์ย่อย


นี่คือสิ่งที่ฉันต้องการในการรักษาสคริปต์ทั้งหมดของฉันและเพียงเรียกว่าจากการทุบตีและรักษาเซสชันปัจจุบัน - นี่คือคำตอบที่สมบูรณ์แบบ
Matt The Ninja

7

คุณสามารถรวมนามแฝงและสคริปต์

alias proj="cd \`/usr/bin/proj !*\`"

โดยมีเงื่อนไขว่าสคริปต์สะท้อนเส้นทางปลายทาง โปรดทราบว่าสิ่งเหล่านั้นเป็น backticks ที่ล้อมรอบชื่อสคริปต์ 

ตัวอย่างเช่นสคริปต์ของคุณอาจเป็น

#!/bin/bash
echo /home/askgelal/projects/java/$1

ข้อดีของเทคนิคนี้คือสคริปต์สามารถใช้พารามิเตอร์บรรทัดคำสั่งจำนวนเท่าใดก็ได้และปล่อยปลายทางที่แตกต่างกันซึ่งคำนวณโดยตรรกะที่ซับซ้อน


3
ทำไม? คุณสามารถใช้: proj() { cd "/home/user/projects/java/$1"; }=> proj "foo"(หรือ, proj "foo bar"<= ในกรณีที่คุณมีช่องว่าง) ... หรือแม้กระทั่ง (ตัวอย่างเช่น): proj() { cd "/home/user/projects/java/$1"; shift; for d; do cd "$d"; done; }=> proj a b c=> ทำเครื่องหมายcdเป็น/home/user/projects/java/a/b/c
ไมเคิล


5

ในไฟล์ ~ / .bash_profile ของคุณ เพิ่มฟังก์ชั่นถัดไป

move_me() {
    cd ~/path/to/dest
}

รีสตาร์ทเครื่องและคุณสามารถพิมพ์

move_me 

และคุณจะถูกย้ายไปยังโฟลเดอร์ปลายทาง


3

คุณสามารถใช้โอเปอเรเตอร์ &&:

cd myDirectory && ls


Downvote: นี่ไม่ได้พยายามตอบคำถามจริงที่นี่ คุณสามารถเรียกใช้คำสั่งสองคำสั่งที่พรอมต์ ( &&หากคุณต้องการให้คำสั่งที่สองเป็นเงื่อนไขในคำสั่งแรกหรือเพียงแค่มี;หรือขึ้นบรรทัดใหม่ระหว่างพวกเขา) แต่การวางสิ่งนี้ไว้ในสคริปต์จะนำคุณกลับไปที่ ไดเรกทอรีใหม่เมื่อcdประสบความสำเร็จจริงหรือไม่ "
tripleee

3

ในขณะที่การจัดหาสคริปต์ที่คุณต้องการเรียกใช้เป็นโซลูชันหนึ่งคุณควรทราบว่าสคริปต์นี้สามารถปรับเปลี่ยนสภาพแวดล้อมของเชลล์ปัจจุบันของคุณได้โดยตรง นอกจากนี้มันเป็นไปไม่ได้ที่จะผ่านการขัดแย้งอีกต่อไป

อีกวิธีที่จะทำคือการใช้สคริปต์ของคุณเป็นฟังก์ชั่นในการทุบตี

function cdbm() {
  cd whereever_you_want_to_go
  echo "Arguments to the functions were $1, $2, ..."
}

เทคนิคนี้ใช้โดย autojump: http://github.com/joelthelion/autojump/wikiเพื่อให้คุณมีการเรียนรู้ที่คั่นหนังสือไดเรกทอรีเปลือก


3

คุณสามารถสร้างฟังก์ชั่นเหมือนด้านล่างในของคุณ.bash_profileและมันจะทำงานได้อย่างราบรื่น

ฟังก์ชั่นต่อไปนี้ใช้พารามิเตอร์ทางเลือกซึ่งเป็นโครงการ ตัวอย่างเช่นคุณสามารถเรียกใช้

cdproj

หรือ

cdproj project_name

นี่คือนิยามฟังก์ชั่น

cdproj(){
    dir=/Users/yourname/projects
    if [ "$1" ]; then
      cd "${dir}/${1}"
    else
      cd "${dir}"
    fi
}

อย่าลืมแหล่งที่มาของคุณ .bash_profile


1
คำตอบที่ดีกว่านามแฝง
Pax0r

โซลูชันนี้ยอดเยี่ยมในความเรียบง่ายและความยืดหยุ่น
Kjartan

3

สิ่งนี้ควรทำในสิ่งที่คุณต้องการ เปลี่ยนเป็นไดเร็กทอรีที่สนใจ (จากภายในสคริปต์) จากนั้นวางเปลือก bash ใหม่

#!/bin/bash

# saved as mov_dir.sh
cd ~/mt/v3/rt_linux-rt-tools/
bash

หากคุณเรียกใช้สิ่งนี้มันจะพาคุณไปยังไดเรกทอรีที่น่าสนใจและเมื่อคุณออกมันจะนำคุณกลับไปที่เดิม

root@intel-corei7-64:~# ./mov_dir.sh

root@intel-corei7-64:~/mt/v3/rt_linux-rt-tools# exit
root@intel-corei7-64:~#

สิ่งนี้จะนำคุณกลับไปยังไดเรกทอรีเดิมเมื่อคุณออก ( CTRL+ d)


3
วางไข่ทุบตีใหม่จะหมายความว่าคุณสูญเสียประวัติของคุณและมันจะเริ่มต้นใหม่
Tisch

2

LOOOOOng หลังจากนั้น แต่ฉันทำสิ่งต่อไปนี้:

สร้างไฟล์ชื่อ case

วางต่อไปนี้ในไฟล์:

#!/bin/sh

cd /home/"$1"

บันทึกแล้ว:

chmod +x case

ฉันยังสร้างนามแฝงใน.bashrc:

alias disk='cd /home/; . case'

ตอนนี้เมื่อฉันพิมพ์:

case 12345

โดยพื้นฐานแล้วฉันกำลังพิมพ์:

cd /home/12345

คุณสามารถพิมพ์โฟลเดอร์ใด ๆ หลังจาก 'กรณี':

case 12

case 15

case 17

ซึ่งชอบพิมพ์:

cd /home/12

cd /home/15

cd /home/17

ตามลำดับ

ในกรณีของฉันเส้นทางยาวกว่ามาก - คนพวกนี้สรุปมันด้วย ~ ข้อมูลก่อนหน้านี้


1
cdในนามแฝงเป็นฟุ่มเฟือยและไม่งดงาม; นามแฝงก็ควรจะ ' ~ / case` แทน ยังcaseเป็นคำหลักที่สงวนไว้ดังนั้นตัวเลือกที่ค่อนข้างแย่สำหรับชื่อ
tripleee

1

คุณไม่จำเป็นต้องใช้สคริปต์เพียงตั้งค่าตัวเลือกที่ถูกต้องและสร้างตัวแปรสภาพแวดล้อม

shopt -s cdable_vars

ในของคุณ~/.bashrcอนุญาตให้cdเนื้อหาของตัวแปรสภาพแวดล้อม

สร้างตัวแปรสภาพแวดล้อมดังกล่าว:

export myjava="/home/tree/projects/java"

และคุณสามารถใช้:

cd myjava

ทางเลือกอื่น


0

หากคุณใช้ปลาเป็นเปลือกของคุณทางออกที่ดีที่สุดคือการสร้างฟังก์ชั่น ยกตัวอย่างเช่นจากคำถามเดิมคุณสามารถคัดลอก 4 บรรทัดด้านล่างและวางลงในบรรทัดคำสั่งปลาของคุณ:

function proj
   cd /home/tree/projects/java
end
funcsave proj

สิ่งนี้จะสร้างฟังก์ชั่นและบันทึกไว้เพื่อใช้ในภายหลัง หากโครงการของคุณเปลี่ยนเพียงทำซ้ำกระบวนการโดยใช้เส้นทางใหม่

หากคุณต้องการคุณสามารถเพิ่มไฟล์ฟังก์ชั่นด้วยตนเองโดยทำดังต่อไปนี้:

nano ~/.config/fish/functions/proj.fish

และป้อนข้อความ:

function proj
   cd /home/tree/projects/java
end

และในที่สุดก็กด ctrl + x เพื่อออกและ y ตามด้วยย้อนกลับเพื่อบันทึกการเปลี่ยนแปลงของคุณ

( หมายเหตุ: วิธีแรกของการใช้ funcsave จะสร้างไฟล์ proj.fish ให้คุณ )


0

ฉันมีสคริปต์ทุบตีแบบง่ายๆที่เรียกว่า p เพื่อจัดการการเปลี่ยนไดเรกทอรีบน
github.com/godzilla/bash-stuff
เพียงแค่ใส่สคริปต์ในไดเรกทอรีช่องเก็บในเครื่องของคุณ (/ usr / local / bin)
และใส่

alias p='. p'

ใน. bashrc ของคุณ


สิ่งนี้ทำอะไร ดูเหมือนว่ามันจะเรียกใช้ตัวเองซ้ำแม้ว่าฉันแน่ใจว่าคุณได้เรียกใช้ก่อนที่มันจะไม่;)
Ryan Taylor

0

บันทึกการอภิปรายฉันจะตั้งไดเรกทอรีทำงานของกระบวนการหลักได้อย่างไร

มันมีคำตอบที่แฮ็กเช่น https://stackoverflow.com/a/2375174/755804 (เปลี่ยนไดเรกทอรีกระบวนการหลักผ่าน gdb อย่าทำเช่นนี้) และhttps://stackoverflow.com/a/51985735/755804 ( คำสั่งtailcdที่อัดฉีดcd dirnameไปยังอินพุตสตรีมของโพรเซสแม่; ถ้างั้นมันก็ควรเป็นส่วนหนึ่งของ bash แทนที่จะแฮ็ค)


0

มันเป็นคำถามเก่า แต่ฉันแปลกใจจริง ๆ ที่ฉันไม่เห็นเคล็ดลับนี้

แทนที่จะใช้ซีดีคุณสามารถใช้

export PWD=the/path/you/want

ไม่จำเป็นต้องสร้าง subshells หรือใช้นามแฝง

โปรดทราบว่ามันเป็นความรับผิดชอบของคุณเพื่อให้แน่ใจว่า / เส้นทาง / คุณ / ต้องการมีอยู่


ไม่ได้ทำงานโชคไม่ดี
ttfreeman

0

ตามที่อธิบายไว้ในคำตอบอื่น ๆ คุณได้เปลี่ยนไดเรกทอรี แต่ภายในsub-shell ที่รันสคริปต์เท่านั้น สิ่งนี้จะไม่ส่งผลกระทบกับเปลือกหลัก

ทางออกหนึ่งคือการใช้ฟังก์ชั่นทุบตีแทนสคริปต์ทุบตี ( sh); โดยการวางโค้ดสคริปต์ทุบตีของคุณลงในฟังก์ชั่น ซึ่งทำให้ฟังก์ชันพร้อมใช้งานเป็นคำสั่งจากนั้นสิ่งนี้จะถูกดำเนินการโดยไม่มีกระบวนการลูกดังนั้นcdคำสั่งใด ๆจะส่งผลกระทบต่อเชลล์ผู้เรียก

ฟังก์ชั่นทุบตี:

คุณลักษณะหนึ่งของโปรไฟล์ทุบตีคือการจัดเก็บฟังก์ชั่นที่กำหนดเองที่สามารถเรียกใช้ในเทอร์มินัลหรือในสคริปต์ทุบตีแบบเดียวกับที่คุณเรียกใช้แอปพลิเคชัน / คำสั่งนี้ยังสามารถใช้เป็นทางลัดสำหรับคำสั่งยาว

เพื่อให้ระบบของคุณใช้งานได้อย่างมีประสิทธิภาพคุณจะต้องคัดลอกฟังก์ชั่นของคุณเมื่อสิ้นสุดไฟล์หลาย ๆ ไฟล์

/home/user/.bashrc
/home/user/.bash_profile
/root/.bashrc
/root/.bash_profile

คุณสามารถsudo kwrite /home/user/.bashrc /home/user/.bash_profile /root/.bashrc /root/.bash_profileแก้ไข / สร้างไฟล์เหล่านั้นได้อย่างรวดเร็ว

ทำอย่างไร :

คัดลอกโค้ดสคริปต์ทุบตีของคุณภายในฟังก์ชั่นใหม่ในตอนท้ายของไฟล์โปรไฟล์ทุบตีและรีสตาร์ทเครื่องของคุณคุณสามารถเรียกใช้cddหรือฟังก์ชั่นที่คุณเขียน

ตัวอย่างสคริปต์

สร้างทางลัดไปcd ..ด้วยcdd

cdd() {
  cd ..
}

ls ทางลัด

ll() {
  ls -l -h
}

ls ทางลัด

lll() {
  ls -l -h -a
}

-2

คุณสามารถดำเนินการบางบรรทัดใน subshell เดียวกันถ้าคุณจบบรรทัดด้วยแบ็กสแลช

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