ฉันมีสคริปต์ที่มีฟังก์ชันบางอย่าง
ฉันสามารถเรียกใช้หนึ่งในฟังก์ชันโดยตรงจากบรรทัดคำสั่งได้หรือไม่?
อะไรทำนองนี้?
myScript.sh func()
ฉันมีสคริปต์ที่มีฟังก์ชันบางอย่าง
ฉันสามารถเรียกใช้หนึ่งในฟังก์ชันโดยตรงจากบรรทัดคำสั่งได้หรือไม่?
อะไรทำนองนี้?
myScript.sh func()
คำตอบ:
หากสคริปต์กำหนดเฉพาะฟังก์ชันและไม่ดำเนินการอื่นใดก่อนอื่นคุณสามารถเรียกใช้สคริปต์ภายในบริบทของเชลล์ปัจจุบันโดยใช้คำสั่งsource
หรือ.
จากนั้นเรียกใช้ฟังก์ชัน ดูhelp source
ข้อมูลเพิ่มเติม
bash
) และexit
จะยุติเฉพาะ subshell แต่ไม่ใช่เทอร์มินัลของคุณ
ในขณะที่คำตอบอื่น ๆ นั้นถูกต้อง - คุณสามารถทำอย่างอื่นได้อย่างแน่นอน: หากคุณมีสิทธิ์เข้าถึงสคริปต์ทุบตีคุณสามารถแก้ไขได้และวางไว้ที่ท้ายพารามิเตอร์พิเศษ"$@"
ซึ่งจะขยายไปยังอาร์กิวเมนต์ของบรรทัดคำสั่ง คุณระบุและเนื่องจากมัน "โดดเดี่ยว" เชลล์จะพยายามเรียกมันแบบคำต่อคำ และคุณสามารถระบุชื่อฟังก์ชันเป็นอาร์กิวเมนต์แรกได้ที่นี่ ตัวอย่าง:
$ cat test.sh
testA() {
echo "TEST A $1";
}
testB() {
echo "TEST B $2";
}
"$@"
$ bash test.sh
$ bash test.sh testA
TEST A
$ bash test.sh testA arg1 arg2
TEST A arg1
$ bash test.sh testB arg1 arg2
TEST B arg2
สำหรับการขัดคุณสามารถตรวจสอบได้ก่อนว่าคำสั่งนั้นมีอยู่และเป็นฟังก์ชัน:
# Check if the function exists (bash specific)
if declare -f "$1" > /dev/null
then
# call arguments verbatim
"$@"
else
# Show a helpful error
echo "'$1' is not a known function name" >&2
exit 1
fi
"$@"
ในกรณีส่วนใหญ่ $@
ไม่ปลอดภัยในบางกรณี
bash test.sh testA testB
?
[ ! -z "$1" ]
แหล่งที่มาอื่น ๆ อีกด้วยจะทำให้เกิดคำสั่งอื่นในรูปแบบ bash
คำสั่งต่อไปนี้จะลงทะเบียนฟังก์ชันในบริบทก่อนจากนั้นจึงเรียกมันว่า:
. ./myScript.sh && function_name
สั้น ๆ ไม่
คุณสามารถนำเข้าฟังก์ชันทั้งหมดในสคริปต์ไปยังสภาพแวดล้อมของคุณด้วยsource
( help source
สำหรับรายละเอียด) ซึ่งจะช่วยให้คุณสามารถเรียกใช้ฟังก์ชันเหล่านั้นได้ นอกจากนี้ยังมีผลในการเรียกใช้สคริปต์ดังนั้นโปรดระวัง
ไม่มีวิธีเรียกใช้ฟังก์ชันจากเชลล์สคริปต์ราวกับว่าเป็นไลบรารีที่ใช้ร่วมกัน
การใช้ case
#!/bin/bash
fun1 () {
echo "run function1"
[[ "$@" ]] && echo "options: $@"
}
fun2 () {
echo "run function2"
[[ "$@" ]] && echo "options: $@"
}
case $1 in
fun1) "$@"; exit;;
fun2) "$@"; exit;;
esac
fun1
fun2
สคริปต์นี้จะเรียกใช้ฟังก์ชัน fun1 และ fun2 แต่ถ้าคุณเริ่มต้นด้วยตัวเลือก fun1 หรือ fun2 มันจะเรียกใช้ฟังก์ชันที่กำหนดด้วย args (หากมีให้) และออกเท่านั้น การใช้
$ ./test
run function1
run function2
$ ./test fun2 a b c
run function2
options: a b c
แก้ไข: คำเตือน - ดูเหมือนว่าจะใช้ไม่ได้ในทุกกรณี แต่ใช้ได้ดีกับสคริปต์สาธารณะจำนวนมาก
หากคุณมีสคริปต์ทุบตีที่เรียกว่า "control" และข้างในนั้นคุณมีฟังก์ชันที่เรียกว่า "build":
function build() {
...
}
จากนั้นคุณสามารถเรียกสิ่งนี้ได้ (จากไดเร็กทอรีที่อยู่):
./control build
หากอยู่ในโฟลเดอร์อื่นสิ่งนั้นจะทำให้:
another_folder/control build
หากไฟล์ของคุณเรียกว่า "control.sh" มันจะทำให้ฟังก์ชันเรียกได้ดังนี้:
./control.sh build
. ./control.sh && build
ฉันมีสถานการณ์ที่ฉันต้องการฟังก์ชั่นจาก bash script ซึ่งจะต้องไม่ถูกเรียกใช้งานก่อน (เช่นโดยsource
) และปัญหา@$
คือ myScript.sh ถูกเรียกใช้สองครั้งดูเหมือนว่า ... ดังนั้นฉันจึงเกิดความคิด เพื่อให้ฟังก์ชันออกมาพร้อมกับ sed:
sed -n "/^func ()/,/^}/p" myScript.sh
และเพื่อเรียกใช้งานในเวลาที่ฉันต้องการฉันใส่ไว้ในไฟล์และใช้source
:
sed -n "/^func ()/,/^}/p" myScript.sh > func.sh; source func.sh; rm func.sh
คุณสามารถเรียกใช้ฟังก์ชันจากอาร์กิวเมนต์บรรทัดคำสั่งดังต่อไปนี้
function irfan() {
echo "Irfan khan"
date
hostname
}
function config() {
ifconfig
echo "hey"
}
$1
เมื่อคุณสิ้นสุดฟังก์ชันใส่ $ 1 เพื่อยอมรับอาร์กิวเมนต์ให้บอกว่าโค้ดด้านบนจะถูกบันทึกไว้ใน fun.sh เพื่อเรียกใช้ฟังก์ชัน ./fun.sh irfan & ./fun.sh config
แก้ไขโพสต์แล้ว แต่ฉันต้องการพูดถึงโซลูชันที่ฉันต้องการ กำหนดสคริปต์ซับเดียวทั่วไปeval_func.sh
:
#!/bin/bash
source $1 && shift && "@a"
จากนั้นเรียกใช้ฟังก์ชันใด ๆ ภายในสคริปต์ผ่าน:
./eval_func.sh <any script> <any function> <any args>...
ปัญหาที่ฉันพบกับโซลูชันที่ยอมรับคือเมื่อจัดหาสคริปต์ที่มีฟังก์ชันของฉันภายในสคริปต์อื่นอาร์กิวเมนต์หลังจะได้รับการประเมินโดยอดีตทำให้เกิดข้อผิดพลาด
exit
ในฟังก์ชันของคุณมันจะปิดเทอร์มินัลหลังจากที่ฟังก์ชันทำงาน มีวิธีแก้ปัญหานี้หรือไม่? @SvenMarnach