Câu trả lời:
Nếu tập lệnh chỉ xác định các chức năng và không làm gì khác, trước tiên bạn có thể thực thi tập lệnh trong ngữ cảnh của trình bao hiện tại bằng cách sử dụng lệnh source
hoặc .
và sau đó chỉ cần gọi hàm. Xem help source
để biết thêm thông tin.
bash
) và exit
sẽ chỉ kết thúc vỏ con chứ không phải thiết bị đầu cuối của bạn.
Chà, trong khi các câu trả lời khác đều đúng - bạn chắc chắn có thể làm điều gì đó khác: nếu bạn có quyền truy cập vào tập lệnh bash, bạn có thể sửa đổi nó và chỉ cần đặt ở cuối tham số đặc biệt "$@"
- sẽ mở rộng đến các đối số của dòng lệnh bạn chỉ định, và vì nó là "một mình" nên shell sẽ cố gắng gọi chúng một cách nguyên văn; và ở đây bạn có thể chỉ định tên hàm làm đối số đầu tiên. Thí dụ:
$ 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
Để đánh bóng, trước tiên bạn có thể xác minh rằng lệnh tồn tại và là một hàm:
# 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
"$@"
trong hầu hết các trường hợp. $@
không an toàn trong một số trường hợp.
bash test.sh testA testB
không?
[ ! -z "$1" ]
nếu không thì nguồn sẽ nâng cao các báo cáo khác trong một số verions bash
Lệnh sau đây đầu tiên đăng ký hàm trong ngữ cảnh, sau đó gọi nó:
. ./myScript.sh && function_name
Một cách ngắn gọn, không.
Bạn có thể nhập tất cả các hàm trong tập lệnh vào môi trường của mình với source
( help source
để biết chi tiết), sau đó sẽ cho phép bạn gọi chúng. Điều này cũng có ảnh hưởng đến việc thực thi script, vì vậy hãy cẩn thận.
Không có cách nào để gọi một hàm từ tập lệnh shell như thể nó là một thư viện được chia sẻ.
Sử dụng 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
Tập lệnh này sẽ chạy các hàm fun1 và fun2 nhưng nếu bạn khởi động nó với tùy chọn fun1 hoặc fun2, nó sẽ chỉ chạy hàm đã cho với args (nếu được cung cấp) và thoát. Sử dụng
$ ./test
run function1
run function2
$ ./test fun2 a b c
run function2
options: a b c
Chỉnh sửa: CẢNH BÁO - có vẻ như điều này không hoạt động trong mọi trường hợp, nhưng hoạt động tốt trên nhiều tập lệnh công khai.
Nếu bạn có một tập lệnh bash được gọi là "control" và bên trong nó, bạn có một chức năng được gọi là "build":
function build() {
...
}
Sau đó, bạn có thể gọi nó như thế này (từ thư mục ở đó):
./control build
Nếu nó nằm trong một thư mục khác, điều đó sẽ làm cho nó:
another_folder/control build
Nếu tệp của bạn được gọi là "control.sh", điều đó sẽ làm cho hàm có thể gọi được như sau:
./control.sh build
. ./control.sh && build
Tôi có một tình huống mà tôi cần một hàm từ tập lệnh bash không được thực thi trước (ví dụ: bởi source
) và vấn đề với @$
myScript.sh sau đó được chạy hai lần, có vẻ như ... Vì vậy, tôi đã nảy ra ý tưởng để lấy chức năng ra với sed:
sed -n "/^func ()/,/^}/p" myScript.sh
Và để thực thi nó vào lúc tôi cần, tôi đặt nó vào một tệp và sử dụng source
:
sed -n "/^func ()/,/^}/p" myScript.sh > func.sh; source func.sh; rm func.sh
bạn có thể gọi hàm từ đối số dòng lệnh như bên dưới
function irfan() {
echo "Irfan khan"
date
hostname
}
function config() {
ifconfig
echo "hey"
}
$1
khi bạn kết thúc hàm, hãy đặt $ 1 để chấp nhận đối số, giả sử mã ở trên được lưu trong fun.sh để chạy hàm ./fun.sh irfan & ./fun.sh config
Bài đã giải quyết nhưng tôi muốn đề cập đến giải pháp ưa thích của mình. Cụ thể, xác định một tập lệnh một lớp lót chung eval_func.sh
:
#!/bin/bash
source $1 && shift && "@a"
Sau đó gọi bất kỳ hàm nào trong bất kỳ tập lệnh nào qua:
./eval_func.sh <any script> <any function> <any args>...
Một vấn đề tôi gặp phải với giải pháp được chấp nhận là khi tìm nguồn cung cấp tập lệnh chứa hàm của tôi trong một tập lệnh khác, các đối số của tập lệnh sau sẽ được đánh giá bởi tập lệnh trước, gây ra lỗi.
exit
trong hàm của mình, nó sẽ đóng thiết bị đầu cuối sau khi hàm được thực thi. Có cách nào để khắc phục điều này? @SvenMarnach