ส่งออกฟังก์ชันในเชลล์


87

โปรดบอกวิธีการส่งออกฟังก์ชันในพาเรนต์เชลล์ (bash, sh หรือ ksh) เพื่อให้ฟังก์ชันนี้พร้อมใช้งานสำหรับกระบวนการย่อยทั้งหมดที่เรียกใช้จากกระบวนการหลัก


คำตอบ:


106

export -fคุณลักษณะเป็นเฉพาะกับทุบตี:

ผู้ปกครอง

#!/bin/bash
plus1 () { echo $(($1 + 1)); }
echo $(plus1 8)
export -f plus1
./child 14 21

เด็ก

#!/bin/bash
echo $(plus1 $(($1 * $2)) )

2
ฟังก์ชั่นส่งออกมีให้เฉพาะสำหรับการโทรของเด็กหรือไม่ จะนำไปใช้กับเซสชันทุบตีปัจจุบันได้อย่างไร? ชอบเขียน. bashrc แต่สำหรับอินสแตนซ์ bash ปัจจุบันเท่านั้น ...
vp_arth

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


3

หากคุณใช้ ksh หรือ zsh:

คุณสามารถใช้ตัวแปรสภาพแวดล้อมFPATHซึ่งคุณสามารถวางฟังก์ชันทั้งหมดของคุณได้

หากFPATHตั้งค่าไว้บนอินเทอร์พรีเตอร์แบบโต้ตอบและไม่พบคำสั่งหรือฟังก์ชันในสภาพแวดล้อมเชลล์ปัจจุบันหรือPATHไดเร็กทอรีที่แสดงรายการจะถูกค้นหาการมีอยู่ของไฟล์ที่ตั้งชื่อตามคำสั่งที่หายไป หากพบจะมีที่มาในสภาพแวดล้อมเชลล์ปัจจุบันและคาดว่าจะกำหนดฟังก์ชัน

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

คุณสามารถใช้autoloadคำสั่งในเชลล์สคริปต์เพื่อโหลดฟังก์ชันที่คุณต้องการ:

autoload fun_a fun_b

ใน zsh autoloadจำเป็นสำหรับFPATHการทำงาน ในkshและญาติสนิทฉันเชื่อว่ามันทำให้ฟังก์ชันที่กำหนดไว้FPATHเพื่อแทนที่คำสั่งปกติใน PATH ของคุณตามที่กำหนดไว้โดยตรง

รายละเอียดบางประการเกี่ยวกับFPATHและautoload:


1

หากคุณสร้าง subshells ด้วยสิ่ง( )นั้นจะสืบทอด snapshot ของนิยามพารามิเตอร์และตัวแปรเชลล์ทั้งหมด

หากคุณดำเนินการเหมือนโปรแกรมคุณสามารถใส่คำจำกัดความ.bashrcได้

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

สคริปต์ Wrapper อาจมีลักษณะดังนี้:

script=$1
shift
. include.sh
. $script "$@"

แนวคิดคือพารามิเตอร์แรกคือชื่อของสคริปต์จริงและพารามิเตอร์ที่เหลือคือ args จากนั้นสคริปต์ด้านบนจะถูกเรียกใช้แทน


2
คุณช่วยอธิบายสิ่งเหล่านี้ด้วยตัวอย่างการเข้ารหัสได้ไหม ฉันไม่ต้องการใส่ฟังก์ชันใน. bashrc
Sachin Chourasiya

1
declare -x -f NAME

ข้อมูลเพิ่มเติม

-f จำกัด การกระทำหรือแสดงชื่อฟังก์ชันและคำจำกัดความ
-x เพื่อทำการส่งออก NAME

6
โปรดทราบว่านี่คือที่เฉพาะเจาะจงเพื่อ bash( ksh's คู่ไปdeclare, typesetมีความ-xตัวเลือก แต่มันจะใช้กับตัวแปรไม่ฟังก์ชันเหมือนกันสำหรับzsh)
mklement0

0

ฟังก์ชันไม่สามารถส่งออกได้ตามธรรมชาติ อย่างไรก็ตามคุณสามารถส่งออกสตริงได้ดังนั้นฉันมีเคล็ดลับเล็กน้อยที่นี่:

func="$(typeset -f funcname)"
export func

ในการนำเข้าฟังก์ชันให้กำหนดใหม่จากสตริงที่ส่งออก:

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