รันคำสั่งเฉพาะในไดเรกทอรีที่กำหนดโดยไม่ต้อง cd'ing หรือไม่


42

มีวิธีดำเนินการคำสั่งในไดเรกทอรีอื่นโดยไม่ต้องไปcdหรือไม่ ฉันรู้ว่าฉันสามารถcdเข้าcdออกได้ง่าย ๆ แต่ฉันแค่สนใจในความเป็นไปได้ที่จะเดินตามขั้นตอนพิเศษ :)


echo "#!/bin/bash; cd $1; exec $2" > /usr/local/bin/execindirectory; chmod +x /usr/local/bin/execindirectoryมันค่อนข้างน่ารำคาญที่จะทำให้สคริปต์ที่ไม่นี้: อาจต้องใช้ความพยายามอีกเล็กน้อยหากคุณต้องการให้รองรับ "แท็ก" ตัวเลือกเช่น-dและเนื้อหา
LawrenceC

ในฐานะที่เป็นรัฐที่ไม่รู้จักผู้ใช้ในคำตอบตัวอย่างทั้งหมดที่คุณให้ไว้ที่นี่และในความคิดเห็นได้รับการแก้ไขได้ดีกว่าโดยวิธีแก้ปัญหาอื่น ๆ ดังนั้นจึงไม่มีความชัดเจนว่าจริงๆแล้วมีปัญหาที่ต้องแก้ไขที่นี่ คุณสามารถเป็นตัวอย่างที่ดีกว่าได้หรือไม่?
Caleb

คำตอบ:


55

ฉันไม่รู้ว่าสิ่งนี้มีค่าหรือไม่ แต่คุณสามารถสร้าง subshell:

$ (cd /var/log && cp -- *.log ~/Desktop)

ไดเรคทอรีจะถูกเปลี่ยนสำหรับเชลล์ย่อยนั้นเท่านั้นดังนั้นคุณจึงไม่ต้องทำงานcd -หลังจากนั้น


2
นั่นคือสิ่งที่ฉันมักจะทำ
Adam Byrtek

ดีมากฉันลืมเรื่องย่อย ๆ ไปเลยมันมีประโยชน์มากในกรณีนี้
Naftuli Kay

4
$ (cd /var/log && cp *.log ~/Desktop)เพื่อหลีกเลี่ยงความวุ่นวายที่อาจเกิดขึ้นย่อยออกอัฒภาคกับสองเครื่องหมาย: ด้วยวิธีนี้หากไม่มีไดเร็กทอรีอยู่จะไม่มีการดำเนินการคำสั่งเพิ่มเติม
Naftuli Kay

หมายเหตุสำหรับคนอื่นที่ไร้เดียงสาเหมือนฉัน: $ at start ไม่ได้เป็นส่วนหนึ่งของคำสั่งทุกอย่างหลังจากนั้น
Maltronic

14

บางโปรแกรมมีตัวเลือกที่คุณสามารถบอกให้chdir (2)ตัวเอง (เช่น GNU tar-C/ --directory)

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

ในความคิดเห็นในคำตอบอื่นคุณให้ตัวอย่าง:

execindirectory -d /var/log "cp *.log ~/Desktop"

เนื่องจาก*.logรูปแบบถูกขยายโดยเชลล์เอง (ไม่ใช่cp ) บางสิ่งจะต้องchdirไปยังไดเร็กทอรีก่อนที่เชลล์จะประเมินคำสั่งของคุณ

หากคุณเพียงแค่สนใจในการหลีกเลี่ยง“ cd back” คุณสามารถใช้ subshell เพื่อแยกเอฟเฟกต์ของcdออกจากอินสแตนซ์ของเชลล์ที่ใช้งานได้

(cd /path/to/dir && some command)

คุณสามารถทำสิ่งนี้ได้ในฟังก์ชั่นเชลล์ (ฉันเลิกทำตัว-dเลือกจากตัวอย่างการใช้งานของคุณเนื่องจากมีจุดเล็ก ๆ สำหรับคำสั่งนี้หากไดเรกทอรีเป็นตัวเลือกจริง ๆ )

runindir() { (cd "$1" && shift && eval "$@"); }

runindir /var/log 'cp *.log ~/Desktop'  # your example
runindir /var/log cp \*.log \~/Desktop  # eval takes multiple args

runindir /var/log cp \*.log ~/Desktop   # it is okay to expand tilde first

2
ฉันชอบวิธีนี้ยกเว้นส่วนตัวฉันจะใช้ pushd / popd
NJ

10

ไม่บ่อนทำลายคุณค่าของคำตอบที่คนอื่นมอบให้ แต่ฉันเชื่อว่าสิ่งที่คุณต้องการคือ:

(cd /path/to && ./executable [ARGS])

หมายเหตุ parens เพื่อเรียกใช้cdใน sub-shell


ฉันไม่คิดอย่างนั้น อย่างที่ฉันเข้าใจเขาต้องการท้ายที่สุดในไดเรกทอรีเริ่มต้น
Adam Byrtek

โอ้ฉันลืมห่อไว้ใน sub-shell ทั้งหมด แก้ไขคำตอบของฉันขอบคุณ
alex

4

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

# Save where you are and cd to other dir
pushd /path/to/dir/that/needs/to/be/current/dir

run-your-command

# Get back where you were at the beginning.
popd

(แก้ไข: รุ่นที่สั้นกว่าเล็กน้อยด้วย @ Random832)


1
คุณสามารถทำได้pushd other-dirแทนที่จะเป็นpushd .; cd other-dir
Random832

@ Random832 จุดดี!
Bruno

2

น่าเศร้าตัวอย่างของคุณ:

execindirectory -d /var/log "cp *.log ~/Desktop"

ไม่ต้องการการเปลี่ยนแปลงกับ dir เพราะ

cp /var/log/*.log ~/Desktop

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

วิธีที่ซับซ้อนในการแก้ปัญหาของคุณซึ่งอยู่ไกลจากความงดงามของโซลูชัน Michaels คือการใช้งานการค้นหาซึ่งมีสวิตช์ '-execdir' ที่จะดำเนินการใน dir ซึ่งเป็นไฟล์ที่พบ นำไปใช้กับตัวอย่างของคุณไม่ดี:

find /var/log -maxdepth 1 -type f -name "*.log" -execdir echo cp {} ~/Desktop ";"

อาจเป็นประโยชน์สำหรับปัญหาที่แท้จริงของคุณ -okdir แทน -execdir จะขอให้คุณยืนยันการร้องขอทุกครั้ง

-okdir และ -execdir อาจต้องติดตั้ง gnu-find ซึ่งโดยทั่วไปจะใช้กับ Linux


1

แล้วไง./your/path/command.shล่ะ


execindirectory -d /var/log "cp *.log ~/Desktop"ไม่จริงผมหมายถึงสิ่งที่ต้องการต่อไปนี้:
Naftuli Kay

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