วิธีการกำหนดฟังก์ชั่น Bash ที่สามารถใช้งานได้โดยสคริปต์ที่แตกต่างกัน


13

ฉันได้กำหนดbashฟังก์ชั่นใน~/.bashrcไฟล์ของฉัน สิ่งนี้ทำให้ฉันใช้มันในเทอร์มินัลเชลล์ อย่างไรก็ตามดูเหมือนว่าจะไม่มีอยู่เมื่อฉันเรียกมันจากภายในสคริปต์

ฉันจะกำหนดbashฟังก์ชั่นที่สคริปต์ใช้งานได้อย่างไร?


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

คุณกำลังใช้งาน/bin/shอยู่ในบรรทัด shebang หรือไม่?
เควิน

คำตอบ:


9

~/.bash_profileและ~/.bashrcไม่ได้ถูกอ่านโดยสคริปต์และฟังก์ชั่นจะไม่ถูกส่งออกโดยค่าเริ่มต้น ในการทำเช่นนั้นคุณสามารถใช้export -fสิ่งต่อไปนี้:

$ cat > script << 'EOF'
#!/bin/bash
foo
EOF
$ chmod a+x script
$ ./script
./script: line 2: foo: command not found
$ foo() { echo "works" ; } 
$ export -f foo
$ ./script
works

export -f fooอาจถูกเรียกใช้~/.bash_profileเพื่อให้ฟังก์ชันนี้พร้อมใช้งานกับสคริปต์หลังจากเข้าสู่ระบบ ถูกเตือนว่าexport -fไม่สามารถพกพาได้

. fileวิธีการแก้ปัญหาที่ดีกว่าจะมาไฟล์ที่มีฟังก์ชั่นการใช้ สิ่งนี้สามารถพกพาได้มากกว่าและไม่ต้องพึ่งพาสภาพแวดล้อมของคุณในการตั้งค่าด้วยวิธีใดวิธีหนึ่ง


ทำไมไม่เพียงแค่ประกาศฟังก์ชั่นเหมือนfunction myFunction { ... }ใน~/.bash_profileและคุณจะไปดี?
สัตว์สะเทินน้ำสะเทินบก

ถ้าฉันเข้าใจคำตอบของคุณอย่างถูกต้อง (เกี่ยวกับการหาไฟล์ด้วยฟังก์ชั่น) นั่นหมายความว่าฉันต้องแหล่งไฟล์อย่างชัดเจนในทุกสคริปต์ซึ่งน่ารำคาญมาก สิ่งนี้ไม่ได้ซับซ้อนน้อยไปกว่าการคัดลอกการวางฟังก์ชันในสคริปต์ทุกตัว ฉันจะบันทึกบางบรรทัดแน่นอน แต่นั่นคือทั้งหมด อย่างไรก็ตามexportโซลูชันดูเหมือนว่าจะทำงานอย่างถูกต้อง ขอบคุณ
Onturenio

@foampile นี่คือสิ่งที่ฉันทำและไม่ทำงานเมื่อเรียกใช้ฟังก์ชันจากสคริปต์
Onturenio

1
@Onturenio: วิธีที่สอง @ chris-down ที่เสนอนั้นดีกว่าจริง ๆ : 1) เมื่อมีคนอ่านสคริปต์พวกเขาทราบดีว่ามันต้องการfooฟังก์ชั่นบางอย่างจากบางคนfile2) คุณสามารถควบคุมเนื้อหาของมันได้fileดีกว่าตรวจสอบให้แน่ใจว่า ไม่เปลี่ยนแปลงfooก่อนที่จะเรียกใช้สคริปต์ของคุณ คุณสามารถเพิ่มการตรวจสอบความปลอดภัยfileเพื่อให้แน่ใจว่าไม่มีการแก้ไขเช่น (ไม่ใช่เรื่องง่าย แต่เป็นไปได้) (ดีคุณสามารถตรวจสอบสิ่งเหล่านั้นบนฟังก์ชั่น foo ที่กำหนดได้ ... แต่คุณจะได้ดริฟท์ของฉัน ^^ ฉันคิดว่าวิธีที่ 2 นั้นสะอาดกว่า) 3) fileจะมีเฉพาะสิ่งที่จำเป็นเท่านั้น
Olivier Dulac

8

.bashrcถูกอ่านโดยเชลล์เชิงโต้ตอบเท่านั้น (จริงที่เปลือก: ทุบตีเป็นโวหารในแง่นี้ทุบตีไม่ได้อ่าน. .bashrcถ้ามันเป็นเปลือกเข้าสู่ระบบแบบโต้ตอบหรือไม่และมีข้อยกเว้นแม้กระทั่งการยกเว้น. ถ้าการปกครองทุบตีเป็นrshdหรือsshdแล้วทุบตีไม่อ่าน.bashrc, ไม่ว่าจะเป็นแบบโต้ตอบหรือไม่)

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

$ cat ~/lib/bash/my_functions.bash
foo () {

$ cat ~/bin/myscript
#!/bin/bash
. ~/lib/bash/my_functions.bash
foo bar

หากคุณต้องการคุณสามารถติดตามคุณสมบัติ autoload ของ ksh ได้ ใส่คำจำกัดความของฟังก์ชันแต่ละรายการลงในไฟล์ที่มีชื่อเหมือนกับฟังก์ชัน แสดงรายการไดเร็กทอรีที่มีนิยามฟังก์ชันในFPATHตัวแปร (รายการไดเร็กทอรีที่คั่นด้วยโคลอน) นี่เป็นค่าประมาณคร่าวๆของ ksh autoloadซึ่งจริง ๆ แล้วโหลดฟังก์ชั่นทันทีแทนการตามต้องการ:

autoload () {
  set -- "$(set +f; IFS=:;
            for d in $FPATH; do
              if [ -r "$d/$1" ]; then echo -E "$d/$1"; break; fi;
            done)"
  [[ -n $1 ]] && . "$1"
}

+1 สำหรับ autoload แม้ว่าฉันจะแนะนำให้ใช้อันที่มาพร้อมกับ bash อันล่าสุดรองรับการโหลดขี้เกียจ
ปลาดาว

0

คุณต้องการฟังก์ชั่นหรือไม่? $PATHถ้าไม่ได้พิจารณาดึงออกมาจากตรรกะเป็นที่แยกจากกันทุบตีสคริปต์ยืนอยู่คนเดียวในของคุณ ตัวอย่างเช่นฉันมีสิ่งนี้ใน~/.bashrc:

# echo public IP address
alias wanip='dig +short myip.opendns.com @resolver1.opendns.com'

~/binอยู่ในฉัน$PATHดังนั้นฉันสร้าง~/bin/wanipด้วยเนื้อหาต่อไปนี้:

#!/bin/bash

# echo public IP address
dig +short myip.opendns.com @resolver1.opendns.com

และวิ่งchmod 0755 ~/bin/wanipไปทำให้มันสามารถปฏิบัติการได้ ตอนนี้ฉันสามารถรันwanipจากสคริปต์อื่น ๆ

ฉันชอบที่มีwanipสคริปต์ Bash แบบสแตนด์อะโลน มันเตือนฉันว่าฉันต้องการตรรกะนี้โดยทั่วไป (นอกเหนือจากเพียงในเซสชั่นทุบตีโต้ตอบของฉันในปัจจุบัน) สคริปต์แค็ปซูลลอจิกและเอกสารเหมือนกัน

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