กำหนดตัวแปรด้วยชื่อตัวแปร


11

เกิดอะไรขึ้นกับสคริปต์นี้ ฉันพยายามกำหนด A1 = 1, B1 = 1, C1 = 1

LIST="A B C"
for x in $LIST
do
    "$x"1=1
done

และผลลัพธ์คือ:

./x.: line 7: A1=1: command not found
./x.: line 7: B1=1: command not found
./x.: line 7: C1=1: command not found

1
ฉันไม่คิดว่าคุณสามารถสร้างตัวแปรในการทุบตีเช่นนี้ นี่คือสิ่งที่อาร์เรย์สำหรับ
Jakuje

3
eval "$x"1=1ใช้ แม้ว่าตามที่ Jakuje กล่าวไว้อาร์เรย์อาจจะเหมาะสมกว่าสำหรับกรณีนี้
Andrea Corbellini

@AndreaCorbellini คุณควรเขียนเป็นคำตอบ
Sparhawk

คำตอบ:


21

การกำหนดตัวแปรมีรูปแบบของชื่อตัวแปรตามด้วยเครื่องหมายเท่ากับแล้วตามด้วยค่า (ทางเลือก)

นี่คือการมอบหมายที่ถูกต้อง:

ABC=123

"$x"1=1ไม่ใช่การมอบหมายที่ถูกต้องเพราะ"$x"1ไม่ใช่ชื่อตัวแปร มันอาจจะเป็นEVAL uated เป็นชื่อตัวแปร แต่มันไม่ได้ ที่จริงแล้วเชลล์เชื่อว่าเป็นคำสั่ง

วิธีหนึ่งในการทำสิ่งที่คุณต้องการบรรลุคือ:

eval "$x"1=1

อีกวิธีหนึ่งในการทุบตี (แต่ไม่ใช่ในเปลือกหอยอื่น) คือ:

declare "$x"1=1

หรือยัง (อีกครั้งทุบตีเท่านั้น):

let "$x"1=1

(ในกรณีของคุณไม่มีความแตกต่างกันมาก)

แต่อย่างที่Jakujeตั้งข้อสังเกตในความคิดเห็นคุณอาจต้องการไปกับอาร์เรย์ถ้าเชลล์ของคุณมี (ksh, bash หรือ zsh)


เพื่อความสมบูรณ์:

  • evalรันคำสั่งโดยพลการ ดังนั้นหากทางด้านขวาของเครื่องหมายเท่ากับคุณมีตัวแปรที่ขยายไปยังคำสั่งบางคำสั่งนั้นจะถูกดำเนินการ รหัสต่อไปนี้:

    x=a
    y='$(echo hello)'
    eval "$x=$y"

    a=helloเทียบเท่ากับ

  • declareเป็น bash ในตัวเพื่อกำหนดตัวแปรและจะไม่รันคำสั่งใด ๆ รหัสต่อไปนี้:

    x=a
    y='$(echo hello)'
    declare "$x=$y"

    a='$(echo hello)'เทียบเท่ากับ

  • letคล้ายกับdeclareที่ไม่ได้ใช้คำสั่ง แต่ขัดกับdeclare, letอาจจะใช้สำหรับดำเนินการทางคณิตศาสตร์:

    let a="1 + 2"

    a=3เทียบเท่ากับ


แม้ABC = 123จะไม่ถูกต้อง เนื่องจากมีการเพิ่มพื้นที่ก่อนและหลังequal(=)เครื่องหมาย
Mahendran Sakkarai

3

bash FAQ มีรายการทางอ้อม ในกรณีส่วนใหญ่การใช้งานสิ่งที่คุณควรทำจริง ๆ คือใช้อาเรย์แบบเชื่อมโยงหรือดัชนี คุณยังสามารถใช้

func_call_by_reference() { # Bash 4.3
    typeset -n ref=$1   # nameref to the variable named by the caller
    ref=( "val1" "val2" ... )  # return an array by reference
}

ดูรายการคำถามที่พบบ่อยสำหรับตัวเลือกเพิ่มเติมสำหรับการทำเช่นนี้ในขณะที่ยังคงหลีกเลี่ยงการevalพูดยุ่ง


0

คุณสามารถใช้รหัสดังต่อไปนี้ ในรหัสเชลล์ของคุณดำเนินการ"$x"1=1เป็นคำสั่งเพราะไม่ใช่การกำหนดตัวแปรที่ถูกต้อง

LIST="A B C"
for x in $LIST
do
    a=$(echo "$x"1)
    let $a=1
done

คุณใช้เปลือกอะไร การใช้ bosh bash 4.1.7 และ 4.3.11 ฉันได้รับข้อผิดพลาดcommand not found <varname>=1เมื่อฉันพยายามทำเช่นนั้น (เห็นได้ชัดว่า <varname> เป็นค่าที่ฉันเก็บไว้a)
Eric Renouf

ตามที่อธิบายโดย @Andrea Corbellini เราต้องใช้ let, ประกาศหรือ eval เพื่อกำหนดค่า ..
AVJ

1
คุณไม่ต้องการechoที่นี่! a="$x"1เพียงแค่ นอกจากนี้ยังletเป็นบริบททางคณิตศาสตร์ดังนั้นคุณสามารถกำหนดตัวเลขได้ด้วย
Peter Cordes

declare $a=foobarโรงงาน
Peter Cordes
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.