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


43

ผมแค่อยากจะเขียนสคริปต์ที่เปลี่ยนแปลง directory

ฉันใส่คำสั่งด้านล่างในไฟล์ /home/alex/pathABC

#!/bin/sh
cd /home/alex/Documents/A/B/C
echo HelloWorld

chmod +x pathABCฉันไม่

ในเทอร์มินัลในขณะที่/home/alexฉันทำงาน./pathABCแต่เอาต์พุตเป็นเพียงHelloWorldและไดเรกทอรีปัจจุบันจะไม่เปลี่ยนแปลง

แล้วมีอะไรผิดปกติ?


คำตอบ:


74

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

ทางเลือกหลายประการ:

1. ลิงก์สัญลักษณ์

วาง symlink ไว้ในบ้านของคุณในเส้นทางที่ยาวซึ่งคุณต้องการเข้าถึงได้ง่าย

$ ln -s /home/alex/Documents/A/B/C ~/pathABC

จากนั้นเข้าถึงไดเรกทอรีด้วย:

$ cd ~/pathABC

2. นามแฝง

ใส่นามแฝงใน ~ / .bashrc ของคุณ:

alias pathABC="cd /home/alex/Documents/A/B/C"

(จากที่นี่ )

3. ฟังก์ชั่น

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

(จากที่นี่ )

4. หลีกเลี่ยงการวิ่งเป็นเด็ก

แหล่งสคริปต์ของคุณแทนที่จะเรียกใช้ การจัดหา (ทำโดย.หรือsource) ทำให้สคริปต์ทำงานในเชลล์เดียวกันแทนที่จะทำงานในเชลล์ย่อยของตัวเอง

$ . ./pathABC

(จากที่นี่และที่นี่ )

5. vars สามารถซีดี

ตั้งค่าcdable_varsตัวเลือกในของคุณ~/.bashrcและสร้างตัวแปรสภาพแวดล้อมไปยังไดเรกทอรี:

shopt -s cdable_vars
export pathABC="/home/alex/Documents/A/B/C"

จากนั้นคุณสามารถใช้ cd pathABC

(จากที่นี่ )


15
ตอนนี้ฉันเข้าใจการใช้source! ฉันมักจะสงสัยทำไมฉันทำsource .bashrcไม่ได้bash .bashrc
hytromo

ตัวเลือก 3 ใช้งานได้ดี ฉันเพิ่งกำหนดฟังก์ชัน go_to_wherever () {cd my / directory} ที่จุดเริ่มต้นของสคริปต์ เรียกว่าก่อนเรียกใช้การดำเนินการในไดเรกทอรีนั้น
i2097i

> 5. vars สามารถซีดี - cd $pathABCใช่ไหม
loxaxs

7

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

The scope of cd command is only for child process not parent


2
เพิ่มไปนี้ @ Alex เพื่อให้บรรลุผลที่คุณกำลังมองหารันสคริปต์ภายในการปกครองโดยการจัดหามันอย่างใดอย่างหนึ่งหรือ. pathABC source pathABC
zwets

4

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

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

#!/bin/sh
cd /home/alex/Documents/A/B/C && ./another_script.sh # (if it is executable)

สคริปต์ที่สองจะเรียกใช้จากไดเรกทอรีใหม่

HelloWorld 

เป็นเพียงผลลัพธ์ของสคริปต์


3
HelloWorld ไม่ได้ "คืน" ไปยังเปลือกหลัก แต่จะส่งออกไปยังเอาต์พุตมาตรฐาน
Mog

อาจชัดเจนกว่านี้ถ้าคุณเรียกใช้pwdในไดเรกทอรีใหม่แทนที่จะเพิ่มสคริปต์ใหม่ให้กับสถานการณ์
wjandrea

0

เนื่องจากสวัสดีโลกเป็นเพียงคำสั่งติดตามลองทำสิ่งนี้:

สร้างไฟล์สคริปต์ทุบตีcd.shที่มี:

#!/bin/bash
echo "/home/mike/Documents/A/B/C"
  • .shขยายเป็นประชุมเก่าให้สคริปต์ทุบตีชื่อไฟล์นามสกุล มันเป็นเครื่องสำอางอย่างหมดจดและมักจะไม่จำเป็น อย่างไรก็ตามในกรณีนี้สิ่งสำคัญคือการแยกความแตกต่างจากcdคำสั่งหลัก

ทำเครื่องหมายไฟล์สคริปต์ทุบตีโดยใช้:

chmod a+x cd.sh

ตอนนี้เรียกใช้ไฟล์:

$ cd $(./cd.sh)
bash: cd: /home/alex/Documents/A/B/C: No such file or directory
  • cd เราทุกคนรู้.
  • $(...) รันคำสั่งภายในวงเล็บและส่งออกผลลัพธ์
  • หากcd.shอยู่ในเส้นทางของคุณคุณไม่จำเป็นต้องระบุว่าอยู่ที่ไหน เรานำหน้าด้วย./เพื่อระบุคำสั่งที่อยู่ในไดเรกทอรีปัจจุบัน
  • echoเอาท์พุทจากสคริปต์จะถูกส่งกลับไปยังผู้ปกครองผ่านcd.sh $(...)พาเรนต์ (พร้อมต์เชลล์ของเรา) ใช้เอาต์พุตนี้และส่งผ่านไปยังcdคำสั่งLinux

อย่างที่คนอื่นพูดถึงกระบวนการลูกไม่สามารถเปลี่ยนไดเรกทอรีของผู้ปกครองได้ นี่เป็นวิธีหนึ่งที่เด็กสามารถบอกผู้ปกครองว่าจะไปที่ไหนหลังจากกระบวนการสิ้นสุดลง


@wjandrea นั่นคือสิ่งที่คุณได้รับจากการเข้ารหัสบนโทรศัพท์! เพิ่งกลับถึงบ้านฉันจะแก้ไขมัน ขอบคุณ อืมเพิ่งตรวจสอบและใช้งานได้ดี อาจเป็น14.04รุ่นที่คุณอ่านประมาณหนึ่งชั่วโมงที่แล้ว
WinEunuuchs2Unix

คุณเปลี่ยนสคริปต์โดยสิ้นเชิง ก่อนหน้านี้มันเป็นเพียงคำสั่งเดียว: cd /home/mike/Documents/A/B/Cซึ่งไม่ได้สร้างผลลัพธ์ใด ๆ ตอนนี้มันecho "/home/mike/Documents/A/B/C"จะผลิตผล
wjandrea

@wjandrea จริงฉันเปลี่ยนวิธีการเรียกสคริปต์ด้วยเช่นกัน แทนที่จะเป็นเรื่องง่าย./cd.shตอนนี้cd $(./cd.sh)แต่มันบรรลุเป้าหมายของเด็ก ๆ ที่เปลี่ยนไดเรกทอรีปัจจุบันของผู้ปกครอง ใช่มันเป็นเรื่องแปลกใหม่ แต่เป็นอีกวิธีหนึ่งที่ฉันหวังว่าผู้คนจะสนใจ
WinEunuuchs2Unix
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.