2013-04-21 32 views
5

Tôi có một kịch bản mà người dùng cần đánh giá nhiều lần, giải pháp im làm việc là đặt các bit đánh giá vào một hàm và chỉ cần gọi hàm mỗi khi tôi cần đánh giá đầu vào. Vấn đề là khi im cố gắng cập nhật biến số $1 (tham chiếu đến tham số biến đầu tiên của hàm) Tôi nhận được thông báo lỗi "$ VARIABLE command not found".Bash gán biến gián tiếp bên trong hàm

Đây là mã:

function input_handler() { 
if is_integer $1; then 
    selid="$1 -1" 
    if [[ "$1" -le "0" ]]; then 
    echo "Please use a simple positive number!" 
    else 
    if [[ "$1" -le "${#array[*]}" ]]; then 
    eval $1="${array[selid]}" 
    echo "Ok, moving on..." 
    else 
    echo "That number seems too large, try again?" 
    fi 
    fi 
else 
    if [ -e $2/$1 ]; then 
    echo "Ok, moving on..." 
    else 
    echo "That item is not on the list, try again!" 
    fi 
fi 
} 

Và lệnh này:

input_handler $doctype $docpath 

Cung cấp sản lượng này:

5 
./test: line 38: 5=sun: command not found 

Ok, di chuyển trên ...

Bây giờ điều này gần như chính xác, nhưng những gì im afte r là doctype = sun, không 5 = mặt trời, nói cách khác tôi cần tên biến số $1 không phải là giá trị của nó. Thay đổi dòng eval $1="${array[selid]}" thành eval doctype="${array[selid]}" khắc phục trường hợp cụ thể này. Nhưng điều này không khắc phục được sự cố của tôi vì tôi cần chạy hàm này trên các biến khác nhau với các tên khác nhau.

Trả lời

-1

Thông số vị trí là chỉ đọc. Vì vậy, những gì bạn muốn làm là không thể. Bạn nên làm điều gì đó như

foo=$1 

và sau đó làm việc với $foo thay vì $1

+0

Ok, nhưng tôi vẫn cần tên $ 1 không phải là giá trị, điều này có khả thi không? –

+1

Thông số vị trí không chỉ đọc. Bạn có thể thay đổi chúng bằng 'set'. – kojiro

0

Bạn không thể cập nhật giá trị của $1 với một nhiệm vụ truyền thống, nhưng bạn có thể cập nhật các tham số vị trí với set dựng sẵn.

$ f() { echo "[email protected]"; set -- a b c; echo "[email protected]"; echo $2; } 
$ f 1 2 3 
1 2 3 
a b c 
b 

Chỉ cần ghi nhớ này sẽ quét sạch tất cả các tham số vị trí bạn không tái thiết lập mỗi lần, vì vậy bạn sẽ cần phải thiết $2 nếu bạn muốn giữ nó xung quanh.

Đặt cược tốt nhất của bạn có thể chỉ định giá trị trong các tham số vị trí cho tên và chỉ sử dụng tên từ đó trở đi.

4

Có lẽ không hoàn toàn hiểu những gì bạn muốn đạt được, nhưng kiểm tra ví dụ tiếp theo:

weirdfunc() { 
    echo " weirdfunc: variable name is: $1" 
    echo " weirdfunc: variable value is: ${!1}" 
    eval "$1=$((${!1} + 1))" #assign 
} 

myvar="5" 
echo "the value of myvar before: $myvar" 

weirdfunc myvar #call with the NAME not with the value, so NOT weridfunc $myvar 

echo "the value of myvar after: $myvar" 

Nói tóm lại - khi bạn muốn làm bất cứ điều gì với biến TÊN trong một chức năng gọi, bạn nên vượt qua NAME của biến và KHÔNG giá trị của nó. Vì vậy, gọi hàm

somefunc NAME 

thay vì

somefunc $NAME 

và sử dụng các cấu trúc ở trên để có được tên và giá trị bên trong hàm.

+0

Có lẽ tôi nên làm rõ những gì tôi muốn làm. Các kịch bản mà tôi đang làm việc trên đường ống ra một danh sách các mục nhập tập tin và nhắc người dùng cho tập tin mà nó nên chọn, nếu một hợp lệ choise nó nên được lưu trữ trong biến $ 1 biến. Bây giờ cho đến nay tất cả mọi thứ hoạt động tốt, nhưng đây là phần khó khăn; Để làm cho kịch bản thân thiện với người dùng hơn, tôi đã thêm số vào trước mỗi mục nhập tệp. Ide là người dùng có thể nhập một số tương ứng thay cho tên tập tin đầy đủ. Nhưng để làm việc này, tôi cần chức năng chuyển đổi choise của mình "like 5" thành tên hợp lệ "như mặt trời" và lưu trữ trong biến $ 1 –

+0

nếu bạn muốn thay đổi giá trị của biến được chuyển __by name__ sử dụng các cấu trúc trên. Nếu bạn muốn đặt $ 1 sử dụng câu trả lời @ kojiro, nhưng thành thật không hiểu tại sao muốn làm điều này, khi bạn có thể sử dụng bất kỳ biến trợ giúp nào ... Tốt nhất bạn có thể làm - hiển thị một ví dụ R RE RÀNG - không có bất kỳ liên quan nào "nếu "Và với phần chính nữa - không chỉ có chức năng một mình ... – jm666

+0

Bạn hoàn toàn đúng! Tôi đã giải quyết vấn đề này bằng cách chỉ thêm biến số trợ giúp helper="${array[selid]}" thay vì eval $1="${array[selid]}" và gọi chức năng này bên ngoài chức năng: input_handler $doctype $docpath
doctype=$helper
Xin lỗi nếu không rõ ràng, im khá mới với stackoverflow và Bash scripting nói chung. Cảm ơn tất cả sự giúp đỡ của bạn! –

0

Nếu bạn bảo vệ tên biến, Bash sẽ đánh giá và gán cho $ 1 thay vì cố gắng thực thi $ 1 = giá trị.

eval "$1"=${array[selid]} 
Các vấn đề liên quan