จะเรียกใช้เชลล์ในตัวได้อย่างไร


14

ฉันต้องการปรับแต่งการทำงานของcdคำสั่งตามความต้องการของฉัน

ฉันกำหนดหน้าที่ดังต่อไปนี้ - function cd () { cd "$@" && pushd "$@"; }

ความตั้งใจของฟังก์ชั่นนี้คือการผลักดันไดเรกทอรีไปยังสแต็กโดยอัตโนมัติเพื่อให้ฉันไม่ต้องพยายามพิมพ์ด้วยตนเองpushd .ทุกครั้ง

แต่ฟังก์ชั่นดังกล่าวข้างต้นเป็นฟังก์ชันเวียนเพียบเช่นการเรียกร้องให้cdมีการตีความว่าจะเป็นฟังก์ชั่นของตัวเองและไม่ได้cdในตัว

ฉันจะอ้างอิงในcdตัวในฟังก์ชั่นนี้ได้อย่างไร

\ฉันรู้ว่านามแฝงสามารถหนีออกมาใช้ เป็นวิธีการหลบหนีฟังก์ชั่นหรือการอ้างอิงในตัวในทางที่ชัดเจนมากขึ้นคืออะไร?

หมายเหตุ: ฉันไม่ต้องการเปลี่ยนชื่อฟังก์ชั่นของฉันเป็นอย่างอื่น


3
ทำไมไม่เพียงalias cd=pushd? คุณคาดหวังว่าจะเกิดอะไรขึ้นเมื่อคุณทำซีดีกับสิ่งที่ไม่ใช่เส้นทางที่แน่นอน (เช่นcd ../)
Patrick

@ แพทริกไม่ได้สนับสนุนpushd -Pแต่คุณถูกต้องดังที่แสดงในคำถามว่ามันfunction cdดูผิดเล็กน้อยเพราะมันเปลี่ยนไดเรกทอรีสองครั้ง
Tino

คำตอบ:


6

commandกองกำลัง builtin ชื่อคำสั่งที่จะตีความว่าเป็น builtin หรือคำสั่งภายนอก (ข้ามนามแฝงและฟังก์ชั่นการค้นหา) มันมีอยู่ในเปลือก POSIX ทั้งหมดรวมถึงทุบตี

cd () { command cd "$@" && pushd "$@"; }

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

ใน bash และ zsh (แต่ไม่ใช่ ksh) คุณสามารถใช้builtinเพื่อบังคับให้ชื่อคำสั่งถูกตีความว่าเป็น builtin โดยไม่รวม aliases ฟังก์ชันและคำสั่งภายนอก


16

Bash มีคำสั่ง (builtin) builtinซึ่งทำสิ่งที่คุณต้องการ การแทนที่cdด้วยbuiltin cdฟังก์ชันของคุณจะแก้ไขการเรียกซ้ำ


1

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

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

ตัวอย่าง wrapper.sh:

#!/bin/bash
function my_wrapper() { wrapped_program $@ && dostuff }

และในเช่น. bash_aliases:

source /path/to/wrapper.sh
alias wrapped_program="my_wrapper"

แต่นี่มันช่างแฮก การใช้commandจะดีกว่าเมื่อเป็นไปได้


-1

เพื่อให้สามารถทำงานกับพา ธ ที่สัมพันธ์กันจำเป็นต้องมีสิ่งต่อไปนี้:

function cd { 
   dir="$(realpath "$@")"
   command cd "$dir"
   pushd "$dir"
}

สิ่งนี้จะถือว่าคุณอยู่ในลินุกซ์ distro ที่ทันสมัยซึ่งมียูทิลิตี้ 'realpath' (RHEL 6 ไม่ได้เป็นตัวอย่าง) หากมี Perl ให้ใช้งาน 'realpath' สามารถจำลองได้โดยใช้:

! realpath $(pwd) > /dev/null 2>&1  && function realpath {
    perl -e "use Cwd realpath; print realpath(\"$1\") . \"\\n\";"
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.