ฉันจะรันโปรแกรมด้วยไดเรกทอรีการทำงานที่แตกต่างจากปัจจุบันจาก Linux shell ได้อย่างไร


352

ใช้เปลือก Linuxฉันจะเริ่มต้นโปรแกรมด้วยไดเรกทอรีการทำงานที่แตกต่างจากไดเรกทอรีการทำงานปัจจุบันได้อย่างไร

ตัวอย่างเช่นผมมีไฟล์ไบนารีhelloworldที่สร้างแฟ้มhello-world.txtในไดเรกทอรีปัจจุบัน ไฟล์นี้เป็นภายในของไดเรกทอรี

/a

/bขณะนี้ผมอยู่ในไดเรกทอรี ฉันต้องการที่จะเริ่มต้นโปรแกรมของฉันทำงาน../a/helloworldและได้รับที่ไหนสักแห่งในไดเรกทอรีที่สามhello-world.txt/c


5
ฉันค้นพบวิธีที่ยากที่จะsuรีเซ็ตไดเรกทอรีการทำงานเป็นไดเรกทอรีบ้านของผู้ใช้ที่คุณระบุก่อนที่จะเรียกใช้-cคำสั่งใด ๆ นี่เป็นประโยชน์กับฉันมาก
Patrick M

คำตอบ:


561

เรียกใช้โปรแกรมเช่นนี้:

(cd /c; /a/helloworld)

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

การจัดการข้อผิดพลาด:เพื่อหลีกเลี่ยงการรันโปรแกรมโดยไม่ต้องเปลี่ยนไดเรกทอรีเช่นเมื่อสะกดผิด/cให้ดำเนินการตามhelloworldเงื่อนไข:

(cd /c && /a/helloworld)

การลดการใช้งานหน่วยความจำ:เพื่อหลีกเลี่ยงการใช้หน่วยความจำเหลือย่อยในขณะที่สวัสดีชาวโลกดำเนินการโทรhelloworldผ่าน exec:

(cd /c && exec /a/helloworld)

[ขอบคุณJosh และ Juliano ที่ให้คำแนะนำในการปรับปรุงคำตอบนี้!]


1
มีวิธีใดบ้างในการส่งผ่านอาร์กิวเมนต์ไปยังเชลล์นี้? เช่นเดียวกับ $ 1 และ $ 2
finiteloop

2
@segfault: subshell มีการเข้าถึงขอบเขตโดยรอบอย่างสมบูรณ์
David Schmitt

ดูเหมือนว่าจะอยู่ในไดเรกทอรีนั้นชั่วคราวใช่ไหม
dhein

1
คุณสามารถส่งผ่านขัดแย้งทั้งหมดโดยการทำ $ * $ @ หรือ "$ @" (ถ้าคุณต้องการที่จะเคารพข้อโต้แย้งคำพูดคู่)
มาร์เซลเดซรอสโก

1
หากฉันเพิ่มบรรทัดนี้ใน /etc/rc.d/rc.local
Pratik Patil

95

คล้ายกับคำตอบของDavid Schmittรวมถึงข้อเสนอแนะของ Josh แต่ไม่ปล่อยให้กระบวนการเชลล์ทำงาน:

(cd /c && exec /a/helloworld)

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



25

ตัวเลือกที่ไม่ต้องการ subshell และสร้างขึ้นเพื่อทุบตี

(pushd SOME_PATH && run_stuff; popd)

การสาธิต:

$ pwd
/home/abhijit
$ pushd /tmp # directory changed
$ pwd
/tmp
$ popd
$ pwd
/home/abhijit

1
ข้อเสนอแนะที่คล้ายกันนี้ทำโดย Sahil มันไม่ทำงานหากคำสั่งล้มเหลว พิจารณาpushd SOME_PATH && run_stuff && popd- หาก run_stuff ล้มเหลวกว่า popd จะไม่ถูกดำเนินการ
Anton Daneyko

การตอบกลับล่าช้านั้นขึ้นอยู่กับการตั้งค่าของไฟล์ bash ทุบตียังคงสามารถรันคำสั่งแม้หลังจากคำสั่งล้มเหลว (ซึ่งแตกต่างจากการใช้ &&) แต่มันสามารถตั้งค่าให้ไม่ได้ไม่ว่าจะใช้ในแฟ้มแล้วมันจะล้มเหลวในการset -e popd
Loren

8
ถึงกระนั้นฉันคิดว่าpushd "${SOME_PATH}" && run_stuff; popdดีกว่าคำตอบปัจจุบันเนื่องจากความหมาย pushd / popd ได้รับการออกแบบมาโดยเฉพาะสำหรับสถานการณ์นี้ในการเข้าสู่ไดเรกทอรีบางส่วนแล้วกลับมาที่เดิม
Marcel Valdez Orozco

มันทำงานอย่างไรตามที่กำหนดไว้ในนามแฝงและฉันต้องผ่านพารามิเตอร์
DrB

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

19
sh -c 'cd /c && ../a/helloworld'

1
ใช้สิ่งนี้สำหรับ jexec ของ FreeBSD เพื่อดำเนินการคำสั่งภายในคุกในไดเรกทอรีทำงานที่ระบุ
MariánČerný

11

ฉันคิดเสมอว่าเครื่องมือ UNIX ควรเขียนเป็นตัวกรองอ่านอินพุตจาก stdin และเขียนเอาต์พุตไปยัง stdout หากเป็นไปได้คุณสามารถเปลี่ยนไบนารี helloworld เพื่อเขียนเนื้อหาของไฟล์ข้อความเป็น stdout แทนไฟล์ที่ต้องการ ด้วยวิธีนี้คุณสามารถใช้เชลล์เพื่อเขียนไฟล์ของคุณได้ทุกที่

$ cd ~ / b

$ ~ / a / helloworld> ~ / c / helloworld.txt


6
+1 เพื่อความถูกต้องแม้ว่าคำตอบจะเป็นเพียงคำตอบต่อพ่วง
David Schmitt


4

วิธีหนึ่งในการทำเช่นนั้นคือการสร้างเชลล์สคริปต์ wrapper

เชลล์สคริปต์จะเปลี่ยนไดเรกทอรีปัจจุบันเป็น / c จากนั้นเรียกใช้ / a / helloworld เมื่อเชลล์สคริปต์ออกแล้วไดเรกทอรีปัจจุบันจะเปลี่ยนกลับเป็น / b

นี่เป็นตัวอย่างสคริปต์เปลือกหอย

#!/bin/bash
cd /c
/a/helloworld

2

ทำไมไม่ทำให้มันง่าย

cd SOME_PATH && run_some_command && cd -

คำสั่ง 'cd' สุดท้ายจะนำคุณกลับไปยังไดเรกทอรี pwd สุดท้าย สิ่งนี้ควรใช้กับระบบ * nix ทั้งหมด


คุณกำลังเขียน @mezhaka ควรมีการพิจารณาว่า :)
Sahil

1
คำเตือน: หากrun_some_commandล้มเหลวcd -จะไม่ถูกดำเนินการ
starbeamrainbowlabs

1

หากคุณต้องการให้มันไปที่ / C เสมอให้ใช้พา ธ สัมบูรณ์เมื่อคุณเขียนไฟล์


0

หากคุณต้องการทำสิ่งนี้ภายในโปรแกรมของคุณฉันจะทำสิ่งต่อไปนี้:

#include <unistd.h>
int main()
{
  if(chdir("/c") < 0 )  
  {
     printf("Failed\n");
     return -1 ;
  }

  // rest of your program...

}

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

-1

จากไดเร็กทอรีปัจจุบันจัดเตรียมพา ธ แบบเต็มไปยังไดเร็กทอรีสคริปต์เพื่อเรียกใช้งานคำสั่ง

/root/server/user/home/bin/script.sh

1
แต่นั่นไม่ได้เปลี่ยนไดเรกทอรีการทำงานเลย - ฉันคิดว่าคุณกำลังตอบคำถามอื่นกับคำถามที่ถูกถาม
Toby Speight

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