Xuất một hàm trong shell


Câu trả lời:


105

Các export -ftính năng là cụ thể cho Bash:

cha mẹ

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

đứa trẻ

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

2
chức năng xuất chỉ có sẵn cho các cuộc gọi con? Làm thế nào để áp dụng nó vào phiên bash hiện tại? như để .bashrc văn bản, nhưng chỉ ví dụ bash hiện tại ...
vp_arth

3
@vp_arth: Nếu bạn không cần hàm trong các cuộc gọi con, bạn không cần xuất nó. Nó có sẵn trong phiên hiện tại theo một trong hai cách (lưu ý rằng nếu nó được xác định trong một tệp, bạn sẽ cần phải nguồn tệp thay vì chạy nó để làm cho nó có sẵn trong phiên hiện tại).
Tạm dừng cho đến khi có thông báo mới.


3

Nếu bạn đang sử dụng ksh hoặc zsh:

Bạn có thể sử dụng biến môi trường FPATH, trong đó bạn có thể đặt tất cả các hàm của mình.

Nếu FPATHđược đặt trên trình thông dịch tương tác và lệnh hoặc hàm không được tìm thấy trong môi trường shell hiện tại hoặc PATH, các thư mục được liệt kê ở đó sẽ được tìm kiếm sự tồn tại của tệp có tên sau lệnh bị thiếu. Nếu một cái được tìm thấy, nó có nguồn trong môi trường shell hiện tại và được mong đợi để xác định chức năng.

Vì vậy, bạn có thể đặt tất cả các chức năng của mình ở một vị trí FPATHvà các tập lệnh con cũng có thể tìm thấy nó.

Bạn có thể sử dụng autoloadlệnh trong các tập lệnh shell để tải các chức năng bạn yêu cầu:

autoload fun_a fun_b

Trong zsh, autoloadlà bắt buộc FPATHđể hoạt động. Trong kshvà những người thân của nó, tôi tin rằng nó chỉ đơn giản khiến các hàm được định nghĩa trong FPATHghi đè lệnh thông thường trong PATH của bạn, giống như chúng sẽ xảy ra nếu được định nghĩa trực tiếp.

Một số chi tiết về FPATHautoload:


1

Nếu bạn tạo các biểu mẫu con bằng ( )thì chúng sẽ kế thừa một ảnh chụp nhanh của tất cả các định nghĩa, tham số và biến shell.

Nếu bạn thực thi chúng giống như các chương trình thì bạn có thể đưa các định nghĩa vào .bashrc.

Nếu bạn đang cố gắng giả mạo một tập lệnh hiện có để thực hiện một trình bao bọc hoặc thay thế cho một lệnh PATH, thì lệnh .bashrcnày sẽ hoạt động tùy thuộc vào chi tiết của việc thực thi. Nếu không, thay vào đó bạn có thể thực thi một tập lệnh trình bao bọc đơn giản thực hiện một .hoặc sourcemột tệp bao gồm xác định các chức năng và sau đó thực hiện điều tương tự với tập lệnh shell với các lệnh được thay thế.

Tập lệnh trình bao bọc có thể trông giống như sau:

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

Ý tưởng là tham số đầu tiên là tên của tập lệnh thực và các tham số còn lại là args, sau đó tập lệnh trên được chạy thay thế.


2
Bạn có thể vui lòng giải thích những điều này với một số ví dụ mã hóa. Tôi không muốn đặt chức năng của tôi trong .bashrc
Sachin Chourasiya

1
declare -x -f NAME

Thêm thông tin

-f hạn chế hành động hoặc hiển thị đối với tên và định nghĩa hàm
-x để xuất NAME

6
Xin lưu ý rằng điều này là cụ thể chobash . ( ksh'S đối tác để declare, typeset, có một -xtùy chọn, nhưng nó chỉ áp dụng cho các biến , không phải chức năng; ditto cho zsh).
mklement0

0

Bản chất các hàm không thể xuất được. Tuy nhiên, bạn có thể xuất chuỗi, vì vậy tôi có một mẹo nhỏ ở đây:

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

Để nhập hàm, hãy xác định lại hàm từ chuỗi đã xuất:

# in subshell
eval "$func"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.