Làm thế nào để xác định bảng băm trong Bash?


Câu trả lời:


938

Bash 4

Bash 4 vốn hỗ trợ tính năng này. Hãy chắc chắn rằng hashbang của tập lệnh của bạn là #!/usr/bin/env bashhoặc #!/bin/bashdo đó bạn không sử dụng sh. Hãy chắc chắn rằng bạn đang thực thi trực tiếp tập lệnh của mình hoặc thực thi scriptvới bash script. (Không thực sự thực hiện một kịch bản Bash với Bash không xảy ra, và sẽ được thực sự khó hiểu!)

Bạn khai báo một mảng kết hợp bằng cách làm:

declare -A animals

Bạn có thể điền nó với các phần tử bằng cách sử dụng toán tử gán mảng bình thường. Ví dụ: nếu bạn muốn có một bản đồ animal[sound(key)] = animal(value):

animals=( ["moo"]="cow" ["woof"]="dog")

Hoặc hợp nhất chúng:

declare -A animals=( ["moo"]="cow" ["woof"]="dog")

Sau đó sử dụng chúng giống như các mảng bình thường. Sử dụng

  • animals['key']='value' để đặt giá trị

  • "${animals[@]}" để mở rộng các giá trị

  • "${!animals[@]}"(chú ý !) để mở rộng các phím

Đừng quên trích dẫn chúng:

echo "${animals[moo]}"
for sound in "${!animals[@]}"; do echo "$sound - ${animals[$sound]}"; done

Bash 3

Trước bash 4, bạn không có mảng kết hợp. Không sử dụng evalđể mô phỏng chúng . Tránh evalnhư bệnh dịch, vì đó bệnh dịch của kịch bản shell. Lý do quan trọng nhất là evalcoi dữ liệu của bạn là mã thực thi (có nhiều lý do khác nữa).

Đầu tiên và quan trọng nhất : Xem xét nâng cấp lên bash 4. Điều này sẽ làm cho toàn bộ quá trình dễ dàng hơn cho bạn.

Nếu có một lý do bạn không thể nâng cấp, declarelà một lựa chọn an toàn hơn nhiều. Nó không đánh giá dữ liệu như mã bash eval, và như vậy không cho phép tiêm mã tùy ý khá dễ dàng.

Hãy chuẩn bị câu trả lời bằng cách giới thiệu các khái niệm:

Đầu tiên, vô cảm.

$ animals_moo=cow; sound=moo; i="animals_$sound"; echo "${!i}"
cow

Thứ hai , declare:

$ sound=moo; animal=cow; declare "animals_$sound=$animal"; echo "$animals_moo"
cow

Mang chúng lại với nhau:

# Set a value:
declare "array_$index=$value"

# Get a value:
arrayGet() { 
    local array=$1 index=$2
    local i="${array}_$index"
    printf '%s' "${!i}"
}

Hãy sử dụng nó:

$ sound=moo
$ animal=cow
$ declare "animals_$sound=$animal"
$ arrayGet animals "$sound"
cow

Lưu ý: declarekhông thể được đặt trong một chức năng. Bất kỳ việc sử dụng nào declarebên trong hàm bash đều biến biến mà nó tạo cục bộ thành phạm vi của hàm đó, nghĩa là chúng ta không thể truy cập hoặc sửa đổi các mảng toàn cục với nó. (Trong bash 4, bạn có thể sử dụng khai báo -g để khai báo các biến toàn cục - nhưng trong bash 4, bạn có thể sử dụng các mảng kết hợp ở vị trí đầu tiên, tránh cách giải quyết này.)

Tóm lược:

  • Nâng cấp lên bash 4 và sử dụng declare -Acho các mảng kết hợp.
  • Sử dụng declaretùy chọn nếu bạn không thể nâng cấp.
  • Cân nhắc sử dụng awkthay thế và tránh vấn đề hoàn toàn.

1
@Richard: Có lẽ, bạn không thực sự sử dụng bash. Là hashbang sh của bạn thay vì bash, hoặc bạn có đang gọi mã của mình bằng sh không? Hãy thử đặt quyền này trước khi khai báo: echo "$ BASH_VERSION $ POSIXLY_CORRECT", nó sẽ xuất ra 4.xvà không y.
lhunath

5
Không thể nâng cấp: lý do duy nhất tôi viết các tập lệnh trong Bash là vì tính di động "chạy mọi nơi". Vì vậy, dựa vào một tính năng không phổ biến của Bash quy tắc tiếp cận này. Đó là một sự xấu hổ, bởi vì nếu không nó sẽ là một giải pháp tuyệt vời cho tôi!
Steve Pitchers

3
Thật đáng tiếc khi OSX mặc định là Bash 3 vì điều này đại diện cho "mặc định" cho nhiều người. Tôi nghĩ rằng sự sợ hãi của ShellShock có thể là sự thúc đẩy họ cần nhưng dường như là không.
ken

13
@ken đó là một vấn đề cấp phép. Bash trên OSX bị kẹt tại bản dựng không được cấp phép GPLv3 mới nhất.
lhunath

2
... Hoặc sudo port install bash, đối với những người (một cách khôn ngoan, IMHO) không muốn tạo các thư mục trong PATH cho tất cả người dùng có thể ghi mà không có sự leo thang đặc quyền theo quy trình rõ ràng.
Charles Duffy

125

Có sự thay thế tham số, mặc dù nó có thể không phải là PC cũng như ... không xác định.

#!/bin/bash

# Array pretending to be a Pythonic dictionary
ARRAY=( "cow:moo"
        "dinosaur:roar"
        "bird:chirp"
        "bash:rock" )

for animal in "${ARRAY[@]}" ; do
    KEY="${animal%%:*}"
    VALUE="${animal##*:}"
    printf "%s likes to %s.\n" "$KEY" "$VALUE"
done

printf "%s is an extinct animal which likes to %s\n" "${ARRAY[1]%%:*}" "${ARRAY[1]##*:}"

Tất nhiên, cách BASH 4 tốt hơn, nhưng nếu bạn cần hack ... chỉ có hack mới làm được. Bạn có thể tìm kiếm mảng / băm với các kỹ thuật tương tự.


5
Tôi sẽ thay đổi điều đó để VALUE=${animal#*:}bảo vệ trường hợpARRAY[$x]="caesar:come:see:conquer"
glenn jackman

2
Cũng rất hữu ích khi đặt dấu ngoặc kép quanh $ {ARRAY [@]} trong trường hợp có khoảng trắng trong khóa hoặc giá trị, như trongfor animal in "${ARRAY[@]}"; do
devguydavid

1
Nhưng hiệu quả không kém? Tôi đang nghĩ O (n * m) nếu bạn muốn so sánh với một danh sách các khóa khác, thay vì O (n) với các hashmap thích hợp (tra cứu thời gian không đổi, O (1) cho một khóa).
CodeManX

1
Ý tưởng là ít về hiệu quả, nhiều hơn về khả năng hiểu / đọc cho những người có nền tảng về perl, python hoặc thậm chí bash 4. Cho phép bạn viết theo cách tương tự.
Bubnoff

1
@CoDEmanX: đây là một hack , một cách giải quyết thông minh và thanh lịch nhưng vẫn thô sơ để giúp những linh hồn tội nghiệp vẫn bị mắc kẹt trong năm 2007 với Bash 3.x. Bạn không thể mong đợi "hashmap thích hợp" hoặc cân nhắc hiệu quả trong một mã đơn giản như vậy.
MestreLion

85

Đây là những gì tôi đang tìm kiếm ở đây:

declare -A hashmap
hashmap["key"]="value"
hashmap["key2"]="value2"
echo "${hashmap["key"]}"
for key in ${!hashmap[@]}; do echo $key; done
for value in ${hashmap[@]}; do echo $value; done
echo hashmap has ${#hashmap[@]} elements

Điều này không làm việc với tôi với bash 4.1.5:

animals=( ["moo"]="cow" )

2
Lưu ý rằng giá trị có thể không chứa dấu cách, nếu không, bạn thêm nhiều phần tử cùng một lúc
rubo77

6
Upvote cho cú pháp hashmap ["key"] = "value" mà tôi cũng thấy thiếu từ câu trả lời được chấp nhận tuyệt vời.
thomanski

@ rubo77 không có khóa, nó thêm nhiều khóa. Có cách nào để khắc phục điều này?
Xeverous

25

Bạn có thể sửa đổi thêm giao diện hput () / hget () để bạn có tên băm như sau:

hput() {
    eval "$1""$2"='$3'
}

hget() {
    eval echo '${'"$1$2"'#hash}'
}

và sau đó

hput capitals France Paris
hput capitals Netherlands Amsterdam
hput capitals Spain Madrid
echo `hget capitals France` and `hget capitals Netherlands` and `hget capitals Spain`

Điều này cho phép bạn xác định các bản đồ khác không xung đột (ví dụ: 'RCapitals' mà quốc gia tìm kiếm theo thành phố thủ đô). Nhưng, dù sao đi nữa, tôi nghĩ bạn sẽ thấy rằng điều này khá kinh khủng, hiệu quả.

Nếu bạn thực sự muốn tra cứu băm nhanh, có một hack khủng khiếp, khủng khiếp thực sự hoạt động rất tốt. Đây là: viết khóa / giá trị của bạn ra một tệp tạm thời, một dòng trên mỗi dòng, sau đó sử dụng 'grep "^ $ key"' để lấy chúng ra, sử dụng các đường ống có cắt hoặc awk hoặc sed hoặc bất cứ thứ gì để lấy các giá trị.

Như tôi đã nói, nghe có vẻ khủng khiếp và nghe có vẻ như nó phải chậm và làm tất cả các loại IO không cần thiết, nhưng trong thực tế thì nó rất nhanh (bộ nhớ cache của đĩa rất tuyệt, phải không?), Ngay cả đối với hàm băm rất lớn những cái bàn. Bạn phải tự thực thi tính duy nhất của khóa, v.v. Ngay cả khi bạn chỉ có vài trăm mục nhập, kết hợp tệp / grep đầu ra sẽ nhanh hơn một chút - theo kinh nghiệm của tôi nhanh hơn nhiều lần. Nó cũng ăn ít bộ nhớ hơn.

Đây là một cách để làm điều đó:

hinit() {
    rm -f /tmp/hashmap.$1
}

hput() {
    echo "$2 $3" >> /tmp/hashmap.$1
}

hget() {
    grep "^$2 " /tmp/hashmap.$1 | awk '{ print $2 };'
}

hinit capitals
hput capitals France Paris
hput capitals Netherlands Amsterdam
hput capitals Spain Madrid

echo `hget capitals France` and `hget capitals Netherlands` and `hget capitals Spain`

1
Tuyệt quá! bạn thậm chí có thể lặp lại nó: for i in $ (compgen -A biến capitols); làm hget "$ i" "" xong
zhaorufei

22

Chỉ cần sử dụng hệ thống tập tin

Hệ thống tệp là một cấu trúc cây có thể được sử dụng làm bản đồ băm. Bảng băm của bạn sẽ là một thư mục tạm thời, các khóa của bạn sẽ là tên tệp và giá trị của bạn sẽ là nội dung tệp. Ưu điểm là nó có thể xử lý các hashtag lớn và không yêu cầu shell cụ thể.

Tạo băm

hashtable=$(mktemp -d)

Thêm một yếu tố

echo $value > $hashtable/$key

Đọc một yếu tố

value=$(< $hashtable/$key)

Hiệu suất

Tất nhiên, nó chậm, nhưng không phải chậm. Tôi đã thử nghiệm nó trên máy của mình, với ổ SSD và btrfs , và nó có khoảng 3000 phần tử đọc / ghi mỗi giây .


1
Phiên bản nào của bash hỗ trợ mkdir -d? (Không phải 4.3, trên Ubuntu 14. Tôi sẽ dùng đến mkdir /run/shm/foo, hoặc nếu nó đã đầy RAM , mkdir /tmp/foo.)
Camille Goudeseune

1
Có lẽ mktemp -dcó nghĩa là thay thế?
Reid Ellis

2
Tò mò sự khác biệt giữa $value=$(< $hashtable/$key)và là value=$(< $hashtable/$key)gì? Cảm ơn!
Helin Wang

1
"Đã thử nó trên máy của tôi" Điều này nghe có vẻ như là một cách tuyệt vời để ghi một lỗ thông qua ổ SSD của bạn. Không phải tất cả các bản phân phối Linux đều sử dụng tmpfs theo mặc định.
kirbyfan64sos

Tôi đang xử lý khoảng 50000 băm. Perl và PHP làm điều đó một sợi tóc dưới 1/2 giây. Nút trong 1 giây và một cái gì đó. Tùy chọn FS nghe có vẻ chậm. Tuy nhiên, bằng cách nào đó chúng ta có thể đảm bảo rằng các tệp chỉ tồn tại trong RAM không?
Rolf

14
hput () {
  eval hash"$1"='$2'
}

hget () {
  eval echo '${hash'"$1"'#hash}'
}
hput France Paris
hput Netherlands Amsterdam
hput Spain Madrid
echo `hget France` and `hget Netherlands` and `hget Spain`

$ sh hash.sh
Paris and Amsterdam and Madrid

31
Thở dài, điều đó dường như xúc phạm không cần thiết và dù sao nó cũng không chính xác. Người ta sẽ không đặt xác thực đầu vào, thoát hoặc mã hóa (xem, tôi thực sự biết) trong ruột của bảng băm, mà là trong một trình bao bọc và càng sớm càng tốt sau khi nhập.
DigitalRoss

@DigitalRoss bạn có thể giải thích việc sử dụng #hash trong tiếng vang eval '$ {hash' "$ 1" '# hash}' là gì ? Đối với tôi có vẻ như tôi là một bình luận không hơn thế. #hash có ý nghĩa đặc biệt nào ở đây không?
Sanjay

@Sanjay ${var#start}xóa văn bản bắt đầu từ đầu giá trị được lưu trong biến var .
jpaugh

11

Hãy xem xét một giải pháp bằng cách sử dụng hàm bash được đọc như được minh họa trong đoạn mã từ tập lệnh tường lửa ufw theo sau. Cách tiếp cận này có lợi thế là sử dụng nhiều bộ trường được phân tách (không chỉ 2) như mong muốn. Chúng tôi đã sử dụng | dấu phân cách vì các bộ xác định phạm vi cổng có thể yêu cầu dấu hai chấm, tức là 6001: 6010 .

#!/usr/bin/env bash

readonly connections=(       
                            '192.168.1.4/24|tcp|22'
                            '192.168.1.4/24|tcp|53'
                            '192.168.1.4/24|tcp|80'
                            '192.168.1.4/24|tcp|139'
                            '192.168.1.4/24|tcp|443'
                            '192.168.1.4/24|tcp|445'
                            '192.168.1.4/24|tcp|631'
                            '192.168.1.4/24|tcp|5901'
                            '192.168.1.4/24|tcp|6566'
)

function set_connections(){
    local range proto port
    for fields in ${connections[@]}
    do
            IFS=$'|' read -r range proto port <<< "$fields"
            ufw allow from "$range" proto "$proto" to any port "$port"
    done
}

set_connections

2
@CharlieMartin: read là một tính năng rất mạnh mẽ và được nhiều lập trình viên bash sử dụng. Nó cho phép các hình thức nhỏ gọn của xử lý danh sách giống như lisp . Ví dụ, trong ví dụ trên, chúng ta có thể loại bỏ phần tử đầu tiên và giữ lại phần còn lại (nghĩa là một khái niệm tương tự với phần đầu tiênphần còn lại trong lisp) bằng cách thực hiện:IFS=$'|' read -r first rest <<< "$fields"
AsymLabs

6

Tôi đồng ý với @lhunath và những người khác rằng mảng kết hợp là cách phù hợp với Bash 4. Nếu bạn bị mắc kẹt với Bash 3 (OSX, các bản phát hành cũ mà bạn không thể cập nhật), bạn cũng có thể sử dụng expr, ở mọi nơi, một chuỗi và biểu thức chính quy. Tôi thích nó đặc biệt là khi từ điển không quá lớn.

  1. Chọn 2 dấu phân cách mà bạn sẽ không sử dụng trong các khóa và giá trị (ví dụ: ',' và ':')
  2. Viết bản đồ của bạn dưới dạng một chuỗi (lưu ý dấu phân cách ',' cũng ở đầu và cuối)

    animals=",moo:cow,woof:dog,"
  3. Sử dụng biểu thức chính quy để trích xuất các giá trị

    get_animal {
        echo "$(expr "$animals" : ".*,$1:\([^,]*\),.*")"
    }
  4. Tách chuỗi để liệt kê các mục

    get_animal_items {
        arr=$(echo "${animals:1:${#animals}-2}" | tr "," "\n")
        for i in $arr
        do
            value="${i##*:}"
            key="${i%%:*}"
            echo "${value} likes to $key"
        done
    }

Bây giờ bạn có thể sử dụng nó:

$ animal = get_animal "moo"
cow
$ get_animal_items
cow likes to moo
dog likes to woof

5

Tôi thực sự thích câu trả lời của Al P nhưng muốn sự độc đáo được thi hành với giá rẻ nên tôi đã tiến thêm một bước - sử dụng một thư mục. Có một số hạn chế rõ ràng (giới hạn tệp thư mục, tên tệp không hợp lệ) nhưng nó sẽ hoạt động trong hầu hết các trường hợp.

hinit() {
    rm -rf /tmp/hashmap.$1
    mkdir -p /tmp/hashmap.$1
}

hput() {
    printf "$3" > /tmp/hashmap.$1/$2
}

hget() {
    cat /tmp/hashmap.$1/$2
}

hkeys() {
    ls -1 /tmp/hashmap.$1
}

hdestroy() {
    rm -rf /tmp/hashmap.$1
}

hinit ids

for (( i = 0; i < 10000; i++ )); do
    hput ids "key$i" "value$i"
done

for (( i = 0; i < 10000; i++ )); do
    printf '%s\n' $(hget ids "key$i") > /dev/null
done

hdestroy ids

Nó cũng thực hiện tốt hơn một chút trong các thử nghiệm của tôi.

$ time bash hash.sh 
real    0m46.500s
user    0m16.767s
sys     0m51.473s

$ time bash dirhash.sh 
real    0m35.875s
user    0m8.002s
sys     0m24.666s

Chỉ cần nghĩ rằng tôi sẽ tham gia. Chúc mừng!

Chỉnh sửa: Thêm hdestroy ()


3

Hai điều, bạn có thể sử dụng bộ nhớ thay vì / tmp trong bất kỳ kernel 2.6 nào bằng cách sử dụng / dev / shm (Redhat) các bản phát hành khác có thể khác nhau. Ngoài ra hget có thể được thực hiện lại bằng cách đọc như sau:

function hget {

  while read key idx
  do
    if [ $key = $2 ]
    then
      echo $idx
      return
    fi
  done < /dev/shm/hashmap.$1
}

Ngoài ra, bằng cách giả sử rằng tất cả các khóa là duy nhất, trả về ngắn mạch vòng lặp đọc và ngăn không phải đọc qua tất cả các mục. Nếu việc triển khai của bạn có thể có các khóa trùng lặp, thì bạn chỉ cần bỏ qua phần trả về. Điều này tiết kiệm chi phí đọc và bỏ cả grep và awk. Sử dụng / dev / shm cho cả hai triển khai mang lại kết quả như sau bằng cách sử dụng thời gian trên hàm băm 3 mục tìm kiếm cho mục cuối cùng:

Grep / Awk:

hget() {
    grep "^$2 " /dev/shm/hashmap.$1 | awk '{ print $2 };'
}

$ time echo $(hget FD oracle)
3

real    0m0.011s
user    0m0.002s
sys     0m0.013s

Đọc / lặp lại:

$ time echo $(hget FD oracle)
3

real    0m0.004s
user    0m0.000s
sys     0m0.004s

trên nhiều yêu cầu, tôi chưa bao giờ thấy ít hơn một sự cải thiện 50%. Tất cả điều này có thể được quy cho ngã ba trên đầu, do sử dụng /dev/shm.


3

Một đồng nghiệp chỉ đề cập đến chủ đề này. Tôi đã triển khai độc lập các bảng băm trong bash và nó không phụ thuộc vào phiên bản 4. Từ một bài đăng trên blog của tôi vào tháng 3 năm 2010 (trước một số câu trả lời ở đây ...) có tiêu đề Bảng bash trong bash :

Trước đây tôi đã sử dụng cksumđể băm nhưng từ đó đã dịch chuỗi hashCode của Java sang bash / zsh gốc.

# Here's the hashing function
ht() {
  local h=0 i
  for (( i=0; i < ${#1}; i++ )); do
    let "h=( (h<<5) - h ) + $(printf %d \'${1:$i:1})"
    let "h |= h"
  done
  printf "$h"
}

# Example:

myhash[`ht foo bar`]="a value"
myhash[`ht baz baf`]="b value"

echo ${myhash[`ht baz baf`]} # "b value"
echo ${myhash[@]} # "a value b value" though perhaps reversed
echo ${#myhash[@]} # "2" - there are two values (note, zsh doesn't count right)

Nó không phải là hai chiều, và cách tích hợp tốt hơn rất nhiều, nhưng dù sao cũng không nên sử dụng. Bash là một lần nhanh chóng, và những thứ như vậy hiếm khi liên quan đến sự phức tạp có thể yêu cầu băm, ngoại trừ có lẽ trong bạn ~/.bashrcvà bạn bè của bạn.


Các liên kết trong câu trả lời là đáng sợ! Nếu bạn nhấp vào nó, bạn bị mắc kẹt trong một vòng lặp chuyển hướng. Vui lòng cập nhật.
Rakib

1
@MohammadRakibAmin - Vâng, trang web của tôi bị sập và tôi nghi ngờ tôi sẽ hồi sinh blog của mình. Tôi đã cập nhật các liên kết ở trên thành một phiên bản lưu trữ. Cảm ơn sự nhiệt tình của bạn!
Adam Katz

2

Trước bash 4, không có cách nào tốt để sử dụng mảng kết hợp trong bash. Đặt cược tốt nhất của bạn là sử dụng một ngôn ngữ diễn giải thực sự có hỗ trợ cho những thứ đó, như awk. Mặt khác, bash 4 không hỗ trợ họ.

Đối với những cách ít tốt hơn trong bash 3, đây là một tài liệu tham khảo có thể giúp ích: http://mywiki.wooledge.org/BashFAQ/006


2

Giải pháp Bash 3:

Khi đọc một số câu trả lời tôi đưa ra một chức năng nhỏ nhanh chóng, tôi muốn đóng góp lại có thể giúp đỡ người khác.

# Define a hash like this
MYHASH=("firstName:Milan"
        "lastName:Adamovsky")

# Function to get value by key
getHashKey()
 {
  declare -a hash=("${!1}")
  local key
  local lookup=$2

  for key in "${hash[@]}" ; do
   KEY=${key%%:*}
   VALUE=${key#*:}
   if [[ $KEY == $lookup ]]
   then
    echo $VALUE
   fi
  done
 }

# Function to get a list of all keys
getHashKeys()
 {
  declare -a hash=("${!1}")
  local KEY
  local VALUE
  local key
  local lookup=$2

  for key in "${hash[@]}" ; do
   KEY=${key%%:*}
   VALUE=${key#*:}
   keys+="${KEY} "
  done

  echo $keys
 }

# Here we want to get the value of 'lastName'
echo $(getHashKey MYHASH[@] "lastName")


# Here we want to get all keys
echo $(getHashKeys MYHASH[@])

Tôi nghĩ rằng đây là một đoạn khá gọn gàng. Nó có thể sử dụng một chút dọn dẹp (mặc dù không nhiều). Trong phiên bản của tôi, tôi đã đổi tên 'khóa' thành 'cặp' và tạo chữ thường KEY và VALUE (vì tôi sử dụng chữ hoa khi các biến được xuất). Tôi cũng đã đổi tên getHashKey thành getHashValue và đặt cả khóa và giá trị cục bộ (mặc dù đôi khi bạn muốn chúng không phải là cục bộ). Trong getHashKeys, tôi không gán bất cứ thứ gì cho giá trị. Tôi sử dụng dấu chấm phẩy để phân tách, vì giá trị của tôi là URL.

0

Tôi cũng đã sử dụng cách bash4 nhưng tôi thấy và lỗi khó chịu.

Tôi cần cập nhật động nội dung mảng kết hợp vì vậy tôi đã sử dụng cách này:

for instanceId in $instanceList
do
   aws cloudwatch describe-alarms --output json --alarm-name-prefix $instanceId| jq '.["MetricAlarms"][].StateValue'| xargs | grep -E 'ALARM|INSUFFICIENT_DATA'
   [ $? -eq 0 ] && statusCheck+=([$instanceId]="checkKO") || statusCheck+=([$instanceId]="allCheckOk"
done

Tôi phát hiện ra rằng với bash 4.3.11 gắn vào khóa hiện có trong dict dẫn đến việc nối thêm giá trị nếu đã có. Vì vậy, ví dụ sau một số lần lặp lại, nội dung của giá trị là "checkKOcheckKOallCheckOK" và điều này không tốt.

Không có vấn đề gì với bash 4.3.39 trong đó việc gắn một khóa tồn tại có nghĩa là thay thế giá trị Actuale nếu đã có.

Tôi đã giải quyết điều này chỉ bằng cách làm sạch / khai báo mảng kết hợp statusCheck trước cicle:

unset statusCheck; declare -A statusCheck

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.