ชื่อตัวแปร bash ไดนามิก (ตัวแปร)


12

ฉันต้องการสร้างลำดับของสตริงแบบไดนามิกโดยจัดการอาเรย์ขององค์ประกอบและสร้างกระบวนการทางคณิตศาสตร์บางอย่าง

for name in FIRST SECOND THIRD FOURTH FIFTH; do
    $name = $(( $6 + 1 ))
    $name = "${$name}q;d"
    echo "${$name}"; printf "\n"
done

ผลที่ปรารถนาจะเป็นดังต่อไปนี้เท่ากับ$60

1q;d
2q;d
3q;d
4q;d
5q;d

แต่ฉันได้รับข้อผิดพลาดนี้

reel_first_part.sh: line 18: FIRST: command not found
reel_first_part.sh: line 19: ${$name}q;d: bad substitution
reel_first_part.sh: line 18: FIRST: command not found
reel_first_part.sh: line 19: ${$name}q;d: bad substitution
reel_first_part.sh: line 18: FIRST: command not found
reel_first_part.sh: line 19: ${$name}q;d: bad substitution

ฉันคิดว่ามันเป็นอะไรที่ง่าย มันเคยทำงานเมื่อฉันทำสิ่งที่ชอบ

FIRST=$(( $6 + 1 ))
FIRST="${FIRST}q;d"

1
คุณช่วยอธิบายให้ดีขึ้นหน่อยได้ไหม ไม่เข้าใจจริงๆว่าคุณกำลังพยายามทำอะไร
เซลล์ประสาท

`$ name = $ (($ 6 + 1)) ควรทำอะไร?
PSkocik

@PSkocik ฉันหวังว่าจะทำFIRST=$(( $6 + 1 ))
giannis christofakis

คำตอบ:


16

แรกของทั้งหมดที่มีไม่สามารถเป็นพื้นที่ใด ๆ รอบในการประกาศตัวแปรใน=bash

evalที่จะได้รับสิ่งที่คุณต้องการคุณสามารถใช้

ตัวอย่างสคริปต์ตัวอย่างเช่นคุณ:

#!/bin/bash
i=0
for name in FIRST SECOND THIRD FOURTH FIFTH; do
    eval "$name"="'$(( $i + 1 ))q;d'"
    printf '%s\n' "${!name}"
    i=$(( $i + 1 ))
done

พิมพ์:

1q;d
2q;d
3q;d
4q;d
5q;d

ใช้evalความระมัดระวังบางคนเรียกมันว่าชั่วร้ายด้วยเหตุผลที่ถูกต้อง

declare จะทำงานด้วย:

#!/bin/bash
i=0
for name in FIRST SECOND THIRD FOURTH FIFTH; do
    declare "$name"="$(( $i + 1 ))q;d"
    printf '%s\n' "${!name}"
    i=$(( $i + 1 ))
done

ยังพิมพ์:

1q;d
2q;d
3q;d
4q;d
5q;d

เป็นสิ่งที่!เครื่องหมายอัศเจรีย์printf '%s\n' "${!name}"หา?
giannis christofakis

1
มันเรียกว่าการขยายตัวทางอ้อมของการขยายตัวbashพารามิเตอร์ .. อ่านสิ่งนี้
heemayl

1
ทุบตีนอกจากนี้ยังมีทางเลือกที่ดีกว่าที่จะdeclare/ :eval printf -v varname '%fmt' argsฟังก์ชั่นภายใน bash-completion บางอย่างใช้สำหรับการโทรโดยอ้างอิง (ส่งชื่อตัวแปรเพื่อเก็บไว้)
Peter Cordes

หมายเหตุ: การใช้declareตั้งค่าตัวแปรในขอบเขตภายในเท่านั้นขณะที่evalวิธีการตั้งค่านั้นเป็นแบบโกลบอล
ผู้ใช้

11

หากคุณต้องการอ้างอิงตัวแปร bash ในขณะที่มีชื่อที่เก็บไว้ในตัวแปรอื่นคุณสามารถทำได้ดังนี้:

$ var1=hello
$ var2=var1
$ echo ${!var2}
hello

คุณจัดเก็บชื่อของตัวแปรที่คุณต้องการเข้าถึงใน, พูด, var2 ในกรณีนี้ จากนั้นคุณสามารถเข้าถึงได้โดย${!<varable name>}ที่<variable name>ตัวแปรถือชื่อของตัวแปรที่คุณต้องการเข้าถึง


มีวิธีพกพาด้วยeval var=\$$holderแต่evalเป็นอันตราย!
gavenkoa


1

สิ่งที่ฉันได้รับจากรหัสของคุณและผลลัพธ์ที่คุณต้องการ (แก้ไขให้ฉันถ้าฉันผิด):
ไม่มีการใช้ชื่อตัวแปร "FIRST" / "SECOND" / ... คุณแค่วนซ้ำพร้อมดัชนี .

สิ่งนี้จะทำงาน:

for i in {1..5} ; do echo $i"q;d" ; done


ใช่คุณพูดถูกยกเว้นนอกจากนี้ฉันต้องการทำฟังก์ชันทางคณิตศาสตร์ด้วยตัวแปร
giannis christofakis

คุณยกตัวอย่างฟังก์ชั่นเลขคณิตนี้ได้หรือไม่? คุณต้องการชื่อตัวแปร (เช่น "THIRD") สำหรับมันหรือเพียงแค่ค่าดัชนี?
csny

SUM=$(($6 + $i)); echo $SUM"q;d"ฉันเห็นสิ่งที่ฉันทำผิด
giannis christofakis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.