นามแฝงในแผ่นซีดีในไดเรกทอรีและเรียกคำสั่ง


21

ฉันมี.bash_profileและในที่ฉันมีชุดของนามแฝง นามแฝงเหล่านั้นในขณะนี้ดำเนินการเพียงคำสั่งเดียวและมันค่อนข้างง่าย อย่างไรก็ตามฉันต้องการทำสองสิ่งด้วยนามแฝงใหม่ที่ฉันพยายามสร้าง

  1. ซีดีลงในไดเรกทอรี
  2. เรียกใช้คำสั่งจากไดเรกทอรีนั้น

คำตอบ:


26

ในการดำเนินการคำสั่งด้วยไดเรกทอรีการทำงานที่เฉพาะเจาะจงมักจะทำ

( cd directory && utility )

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

ตัวอย่าง:

( cd / && echo "$PWD" )  # will output "/"
echo "$PWD"              # will output whatever directory you were in at the start

สิ่งนี้ไม่สามารถเปลี่ยนเป็นนามแฝงทั่วไปได้เนื่องจากนามแฝงไม่สามารถโต้แย้งได้

สำหรับไดเรกทอรีและยูทิลิตี้ที่เฉพาะเจาะจงหนึ่งสามารถทำได้

alias cdrun='( cd "$HOME/somedir" && ./script.sh )'

แต่สำหรับกรณีทั่วไปคุณจะต้องใช้ฟังก์ชันเชลล์:

cdrun () {
    ( cd "$1" && shift && command "$@" )
}

หรือ

cdrun () (
    cd "$1" && shift && command "$@"
)

แทนที่วงเล็บปีกกาด้วยวงเล็บรอบ ๆ ร่างกายของฟังก์ชั่นทำให้ฟังก์ชั่นการดำเนินการใน subshell ของตัวเอง

นี้จะใช้เป็น

$ cdrun "$HOME/somedir" ./script.sh

ซึ่งจะเรียกใช้สคริปต์ที่script.shอยู่ในไดเรกทอรี$HOME/somedirโดย$HOME/somedirเป็นไดเรกทอรีการทำงานหรือ

$ cdrun / ls -l

ซึ่งจะช่วยให้คุณมีรายชื่อไดเรกทอรีใน "รูปแบบยาว" ของไดเรกทอรีราก

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


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

alias thing='$HOME/somedir/script.sh'

แต่นี้จะทำงานscript.shอยู่ใน$HOME/somedirกับปัจจุบันไดเรกทอรีเป็นไดเรกทอรีการทำงาน

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

PATH="$PATH:$HOME/somedir"

script.shในตอนนี้$HOME/somedirจะสามารถเรียกใช้ได้จากทุกที่โดยใช้

$ script.sh

อีกครั้งนี้จะไม่เปลี่ยนไดเรกทอรีทำงานสำหรับคำสั่ง


2
คำตอบที่ครอบคลุมและยอดเยี่ยม ผมแค่คิดว่าฉันต้องการพูดถึงว่านิยามฟังก์ชันเฉพาะความต้องการวิธีการหนึ่งของคำสั่งการจัดกลุ่มและวงเล็บ subshell cdrun () ( cd "$1" && shift && command "$@" )เป็นพอ:
Anthony G - ความยุติธรรมสำหรับโมนิก้า

2
@AnthonyGeoghegan อ้านั่นเป็นเรื่องจริง ฉันมักจะใช้{ ... }เพื่อความสอดคล้องกับฟังก์ชั่นอีกต่อไปแม้ว่า
Kusalananda

คำถามและคำตอบนี้ดูเหมือนจะพูดถึงสถานการณ์ของฉันและอาจเป็นการปรับปรุงโดยใช้สภาพแวดล้อมpushdและpopd( > /dev/nullถ้าคุณพยายามหลีกเลี่ยงข้อความที่ส่งออกเช่นกัน) ในขณะที่รักษาบริบทให้สะอาด!
Pysis

1
@Pysis ใช่(cd dir && thing)ยังเป็นแบบพกพามากขึ้นกว่าการใช้และpushd popd
Kusalananda

@ Kusalananda จริงเหรอ? ฉันให้พวกเขาทำงานอย่างน้อยหลายระบบ
Pysis

4
alias <name-of-the-alias>='cd <the-directory> && <command>'

ดังนั้นหากคุณต้องการเปลี่ยน directory (cd) ลงในโฟลเดอร์/var/log/แล้ว list (ls) ไฟล์ของมันคุณสามารถต่อท้าย.bash_profileไฟล์ของคุณในไฟล์ต่อไปนี้:

alias logs='cd /var/log/ && ls'

1

ฉันใช้ฟังก์ชั่นนี้เพื่อเรียกใช้คำสั่งเดียวในไดเรกทอรีอื่น:

cd1 () {
  if [ $# -eq 1 ]; then
    command cd -- "$1"
  else
    ( command cd -- "$1" && shift && "$@" )
  fi
}

ข้อ จำกัด ของฟังก์ชั่นนี้คือสัญลักษณ์ตัวแทนจะเสร็จสมบูรณ์สัมพันธ์กับไดเรกทอรีเดิมไม่ใช่ที่เกี่ยวข้องกับไดเรกทอรีที่คำสั่งทำงาน มันเป็นไปได้ที่จะทำดีใน zsh

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


-1

แยกคำสั่งด้วยเครื่องหมายอัฒภาคเช่น:

alias do_something='cd /tmp; ls'

8
หากcdล้มเหลวคุณจะได้รับรายชื่อไดเรกทอรีของไดเรกทอรีผิด มันจะดีกว่าที่จะใช้&&แทนที่;นี่
Kusalananda

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