Tentukan variabel dengan nama variabel

11

Apa yang salah dengan skrip ini? Saya mencoba mendefinisikan A1 = 1, B1 = 1, C1 = 1

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

dan hasilnya adalah:

./x.: line 7: A1=1: command not found
./x.: line 7: B1=1: command not found
./x.: line 7: C1=1: command not found
Ake Blomberg
sumber
1
Saya tidak berpikir Anda dapat membuat variabel dalam bash seperti ini. Ini untuk apa array.
Jakuje
3
Gunakan eval "$x"1=1. Meskipun, seperti dicatat Jakuje, array mungkin lebih cocok untuk kasus ini.
Andrea Corbellini
@AndreaCorbellini Anda harus menuliskannya sebagai jawaban.
Sparhawk

Jawaban:

21

Tugas variabel memiliki bentuk nama variabel, diikuti oleh tanda sama dengan, diikuti oleh nilai (opsional).

Ini adalah tugas yang valid:

ABC=123

"$x"1=1bukan tugas yang valid, karena "$x"1bukan nama variabel. Mungkin eval uated untuk nama variabel, tetapi tidak. Shell, pada kenyataannya, percaya itu adalah perintah.

Salah satu cara untuk melakukan apa yang ingin Anda capai adalah ini:

eval "$x"1=1

Cara lain di bash (tetapi tidak di shell lain) adalah:

declare "$x"1=1

Atau juga (khusus lagi bash):

let "$x"1=1

(Tidak ada banyak perbedaan dalam kasus Anda.)

Tetapi, seperti yang dicatat Jakuje dalam komentar , Anda mungkin ingin menggunakan array, jika shell Anda memilikinya (ksh, bash atau zsh).


Untuk kelengkapan:

  • evalmengeksekusi perintah sewenang-wenang. Jadi, jika di sisi kanan tanda sama dengan Anda memiliki variabel yang mengembang ke beberapa perintah, perintah itu akan dieksekusi. Kode berikut:

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

    setara dengan a=hello.

  • declareadalah bash builtin untuk menetapkan variabel dan tidak akan menjalankan perintah apa pun. Kode berikut:

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

    setara dengan a='$(echo hello)'.

  • letmirip dengan declare, dalam hal itu tidak menjalankan perintah. Tetapi bertentangan dengan declare, letdapat digunakan untuk operasi aritmatika:

    let a="1 + 2"

    setara dengan a=3.

Andrea Corbellini
sumber
Bahkan ABC = 123tidak valid. Karena spasi ditambahkan sebelum dan sesudah equal(=)tanda.
Mahendran Sakkarai
3

FAQ bash memiliki entri tentang tipuan. Dalam kebanyakan kasus penggunaan, apa yang seharusnya Anda lakukan adalah menggunakan array asosiatif atau indeks. Anda juga bisa menggunakan

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
}

Lihat entri FAQ untuk lebih banyak opsi untuk melakukan ini sambil tetap menghindari penawaran yang berantakan eval.

Peter Cordes
sumber
0

Anda dapat menggunakan kode seperti berikut. Dalam shell kode Anda dieksekusi "$x"1=1sebagai perintah karena itu bukan penugasan variabel yang valid.

LIST="A B C"
for x in $LIST
do
    a=$(echo "$x"1)
    let $a=1
done
AVJ
sumber
Shell apa yang Anda gunakan? Menggunakan bosh bash 4.1.7 dan 4.3.11 Saya mendapatkan kesalahan tentang command not found <varname>=1ketika saya mencoba melakukan itu (jelas dengan <varname> menjadi nilai yang saya simpan a)
Eric Renouf
seperti yang dijelaskan oleh @Andrea Corbellini, kita harus menggunakan biarkan, deklarasikan atau eval untuk memberikan nilai ..
AVJ
1
kamu tidak perlu di echosini! Adil a="$x"1. Juga letmerupakan konteks aritmatika, jadi Anda hanya dapat menetapkan angka dengannya.
Peter Cordes
declare $a=foobarbekerja.
Peter Cordes