Tôi có một hàm bash tạo ra một số đầu ra:
function scan {
echo "output"
}
Làm cách nào để gán đầu ra này cho một biến?
I E. VAR = quét (tất nhiên điều này không hoạt động - nó làm cho VAR bằng với chuỗi "quét")
Câu trả lời:
VAR=$(scan)
Chính xác giống như cách đối với các chương trình.
Bạn có thể sử dụng các hàm bash trong các lệnh / đường dẫn như cách bạn sử dụng các chương trình thông thường. Các chức năng cũng có sẵn để kiểm tra con và tạm thời, Thay thế lệnh:
VAR=$(scan)
Là cách đơn giản để đạt được kết quả bạn muốn trong hầu hết các trường hợp. Tôi sẽ nêu ra những trường hợp đặc biệt dưới đây.
Duy trì các dòng mới theo sau:
Một trong những tác dụng phụ (thường hữu ích) của Thay thế Lệnh là nó sẽ loại bỏ bất kỳ số lượng dòng mới ở cuối. Nếu muốn duy trì các dòng mới ở cuối, người ta có thể nối thêm một ký tự giả vào đầu ra của vỏ con, và sau đó tách nó ra bằng cách mở rộng tham số.
function scan2 () {
local nl=$'\x0a'; # that's just \n
echo "output${nl}${nl}" # 2 in the string + 1 by echo
}
# append a character to the total output.
# and strip it with %% parameter expansion.
VAR=$(scan2; echo "x"); VAR="${VAR%%x}"
echo "${VAR}---"
bản in (giữ 3 dòng mới):
output
---
Sử dụng tham số đầu ra: tránh vỏ con (và duy trì các dòng mới)
Nếu những gì hàm cố gắng đạt được là "trả về" một chuỗi thành một biến, với bash v4.3 trở lên, người ta có thể sử dụng cái được gọi là a nameref
. Namerefs cho phép một hàm lấy tên của một hoặc nhiều tham số đầu ra của biến. Bạn có thể gán mọi thứ cho một biến nameref và giống như thể bạn đã thay đổi biến mà nó 'trỏ tới / tham chiếu'.
function scan3() {
local -n outvar=$1 # -n makes it a nameref.
local nl=$'\x0a'
outvar="output${nl}${nl}" # two total. quotes preserve newlines
}
VAR="some prior value which will get overwritten"
# you pass the name of the variable. VAR will be modified.
scan3 VAR
# newlines are also preserved.
echo "${VAR}==="
bản in:
output
===
Hình thức này có một vài ưu điểm. Cụ thể, nó cho phép hàm của bạn sửa đổi môi trường của người gọi mà không cần sử dụng các biến toàn cục ở mọi nơi.
Lưu ý: việc sử dụng namerefs có thể cải thiện hiệu suất của chương trình của bạn rất nhiều nếu các chức năng của bạn phụ thuộc nhiều vào nội trang bash, vì nó tránh được việc tạo ra một subhell bị vứt bỏ ngay sau đó. Điều này thường có ý nghĩa hơn đối với các hàm nhỏ được sử dụng lại thường xuyên, ví dụ: các hàm kết thúc bằngecho "$returnstring"
Điều này có liên quan. https://stackoverflow.com/a/38997681/5556676
Tôi nghĩ rằng init_js nên sử dụng khai báo thay vì cục bộ!
function scan3() {
declare -n outvar=$1 # -n makes it a nameref.
local nl=$'\x0a'
outvar="output${nl}${nl}" # two total. quotes preserve newlines
}
local
BUILTIN sẽ chấp nhận bất kỳ tùy chọn mà các declare
BUILTIN sẽ chấp nhận. từ một thử nghiệm nhanh, nó cũng giống như declare -n
trong một phạm vi hàm cũng cung cấp cho phạm vi cục bộ biến. Có vẻ như chúng có thể hoán đổi cho nhau ở đây.