ฉันมีฟังก์ชันทุบตีที่ให้ผลลัพธ์บางอย่าง:
function scan {
echo "output"
}
ฉันจะกำหนดผลลัพธ์นี้ให้กับตัวแปรได้อย่างไร
กล่าวคือ. VAR = scan (แน่นอนว่าไม่ได้ผล - ทำให้ VAR เท่ากับสตริง "scan")
ฉันมีฟังก์ชันทุบตีที่ให้ผลลัพธ์บางอย่าง:
function scan {
echo "output"
}
ฉันจะกำหนดผลลัพธ์นี้ให้กับตัวแปรได้อย่างไร
กล่าวคือ. VAR = scan (แน่นอนว่าไม่ได้ผล - ทำให้ VAR เท่ากับสตริง "scan")
คำตอบ:
VAR=$(scan)
วิธีเดียวกับโปรแกรม
คุณสามารถใช้ฟังก์ชัน bash ในคำสั่ง / pipelines ได้เช่นเดียวกับที่คุณใช้โปรแกรมทั่วไป ฟังก์ชั่นนี้ยังพร้อมใช้งานสำหรับ subshells และสกรรมกริยาการแทนที่คำสั่ง:
VAR=$(scan)
เป็นวิธีที่ตรงไปตรงมาเพื่อให้บรรลุผลลัพธ์ที่คุณต้องการในกรณีส่วนใหญ่ ฉันจะร่างกรณีพิเศษด้านล่าง
การรักษา Newlines ต่อท้าย:
ผลข้างเคียงอย่างหนึ่ง (มักจะเป็นประโยชน์) ของการแทนที่คำสั่งคือมันจะตัดบรรทัดใหม่ที่ต่อท้ายออก หากต้องการรักษาบรรทัดใหม่ต่อท้ายเราสามารถต่อท้ายอักขระดัมมี่เข้ากับเอาต์พุตของ subshell และต่อจากนั้นจึงดึงออกด้วยการขยายพารามิเตอร์
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}---"
พิมพ์ (3 บรรทัดใหม่เก็บไว้):
output
---
ใช้พารามิเตอร์เอาต์พุต: หลีกเลี่ยง subshell (และรักษาบรรทัดใหม่)
หากสิ่งที่ฟังก์ชันพยายามบรรลุคือการ "คืนค่า" สตริงให้เป็นตัวแปรโดยใช้ bash v4.3 ขึ้นไปเราสามารถใช้สิ่งที่เรียกว่า a nameref
. Namerefs อนุญาตให้ฟังก์ชันใช้ชื่อของพารามิเตอร์เอาต์พุตของตัวแปรอย่างน้อยหนึ่งตัว คุณสามารถกำหนดสิ่งต่างๆให้กับตัวแปร nameref และเหมือนกับว่าคุณเปลี่ยนตัวแปรที่ 'ชี้ไปที่ / อ้างอิง'
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}==="
พิมพ์:
output
===
แบบฟอร์มนี้มีข้อดีเล็กน้อย กล่าวคืออนุญาตให้ฟังก์ชันของคุณแก้ไขสภาพแวดล้อมของผู้โทรโดยไม่ต้องใช้ตัวแปรส่วนกลางทุกที่
หมายเหตุ: การใช้ namerefs สามารถปรับปรุงประสิทธิภาพของโปรแกรมของคุณได้อย่างมากหากฟังก์ชันของคุณต้องพึ่งพา bash builtins เป็นอย่างมากเนื่องจากจะหลีกเลี่ยงการสร้าง subshell ที่ถูกทิ้งในภายหลัง โดยทั่วไปสิ่งนี้เหมาะสมกว่าสำหรับฟังก์ชันขนาดเล็กที่ใช้ซ้ำบ่อยครั้งเช่นฟังก์ชันที่ลงท้ายด้วยecho "$returnstring"
สิ่งนี้มีความเกี่ยวข้อง https://stackoverflow.com/a/38997681/5556676
ฉันคิดว่า init_js ควรใช้การประกาศแทน local!
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 จะยอมรับตัวเลือกใด ๆ ว่าdeclare
builtin จะยอมรับ จากการทดสอบอย่างรวดเร็วดูเหมือนว่าdeclare -n
ในขอบเขตฟังก์ชันยังให้ขอบเขตโลคัลของตัวแปร ดูเหมือนว่าจะใช้แทนกันได้ที่นี่