Xác định các biến có tên biến


11

Có gì sai với kịch bản này? Tôi đang cố gắng xác định A1 = 1, B1 = 1, C1 = 1

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

và kết quả là:

./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
Tôi không nghĩ bạn có thể tạo các biến trong bash như thế này. Đây là những mảng cho.
Jakuje

3
Sử dụng eval "$x"1=1. Mặc dù, như Jakuje lưu ý, mảng có lẽ phù hợp hơn cho trường hợp này.
Andrea Corbellini

@AndreaCorbellini Bạn nên viết nó như một câu trả lời.
Sparhawk

Câu trả lời:


21

Một phép gán biến có dạng tên biến, theo sau là dấu bằng, theo sau là giá trị (tùy chọn).

Đây là một nhiệm vụ hợp lệ:

ABC=123

"$x"1=1không phải là một bài tập hợp lệ, vì "$x"1không phải là một tên biến. Nó có thể là eval uated để một tên biến, nhưng nó không phải là. Vỏ, trên thực tế, tin rằng nó là một lệnh.

Một cách để làm những gì bạn muốn đạt được là:

eval "$x"1=1

Một cách khác trong bash (nhưng không phải trong các shell khác) là:

declare "$x"1=1

Hoặc cũng (một lần nữa chỉ bash):

let "$x"1=1

(Không có nhiều khác biệt trong trường hợp của bạn.)

Nhưng, như Jakuje đã lưu ý trong các bình luận , có lẽ bạn muốn đi với mảng, nếu vỏ của bạn có chúng (ksh, bash hoặc zsh).


Để hoàn thiện:

  • evalthực thi các lệnh tùy ý. Vì vậy, nếu ở phía bên phải của dấu bằng bạn có một biến mở rộng thành một số lệnh, lệnh đó sẽ được thực thi. Các mã sau đây:

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

    tương đương với a=hello.

  • declarelà một bash dựng sẵn để gán các biến và sẽ không thực hiện bất kỳ lệnh nào. Các mã sau đây:

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

    tương đương với a='$(echo hello)'.

  • lettương tự như declareở chỗ nó không thực thi các lệnh. Nhưng trái với declare, letcó thể được sử dụng cho các hoạt động số học:

    let a="1 + 2"

    tương đương với a=3.


Thậm chí ABC = 123là không hợp lệ. Bởi vì không gian được thêm vào trước và sau equal(=)dấu hiệu.
Mahendran Sakkarai

3

Câu hỏi thường gặp về bash có một mục trên hướng dẫn. Trong hầu hết các trường hợp sử dụng, những gì bạn thực sự nên làm là sử dụng một mảng kết hợp hoặc được lập chỉ mục. Bạn cũng có thể dùng

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
}

Xem mục Câu hỏi thường gặp đó để có thêm tùy chọn để thực hiện việc này trong khi vẫn tránh evaltrích dẫn lộn xộn .


0

Bạn có thể sử dụng mã như sau. Trong shell code của bạn thực thi "$x"1=1như một lệnh bởi vì nó không phải là một phép gán biến hợp lệ.

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

Bạn đang sử dụng vỏ gì? Sử dụng bosh bash 4.1.7 và 4.3.11 Tôi gặp lỗi command not found <varname>=1khi tôi cố gắng làm điều đó (rõ ràng với <varname> là giá trị tôi lưu trữ a)
Eric Renouf

như được giải thích bởi @Andrea Corbellini, chúng tôi phải sử dụng let, khai báo hoặc eval để gán giá trị ..
AVJ

1
bạn không cần echoở đây! Chỉ cần a="$x"1. Cũng letlà một bối cảnh số học, vì vậy bạn chỉ có thể gán số với nó.
Peter Cordes

declare $a=foobarlàm.
Peter Cordes
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.