Melewati array sebagai parameter dalam bash

188

Bagaimana saya bisa melewatkan array sebagai parameter ke fungsi bash?

Catatan: Setelah tidak menemukan jawaban di sini di Stack Overflow, saya memposting solusi yang agak kasar sendiri. Ini memungkinkan hanya satu array yang diteruskan, dan itu menjadi elemen terakhir dari daftar parameter. Sebenarnya, ia tidak melewatkan array sama sekali, tetapi daftar elemen-elemennya, yang dirakit kembali menjadi array dengan dipanggil_fungsi (), tetapi berhasil bagi saya. Jika seseorang tahu cara yang lebih baik, silakan menambahkannya di sini.

DevSolar
sumber
1
Di sini Anda memiliki referensi yang bagus dan banyak contoh.
Artem Barger
16
Errr ... Tiga downvotes pada pertanyaan lima tahun dalam menit yang sama?
DevSolar

Jawaban:

220

Anda dapat melewati beberapa array sebagai argumen menggunakan sesuatu seperti ini:

takes_ary_as_arg()
{
    declare -a argAry1=("${!1}")
    echo "${argAry1[@]}"

    declare -a argAry2=("${!2}")
    echo "${argAry2[@]}"
}
try_with_local_arys()
{
    # array variables could have local scope
    local descTable=(
        "sli4-iread"
        "sli4-iwrite"
        "sli3-iread"
        "sli3-iwrite"
    )
    local optsTable=(
        "--msix  --iread"
        "--msix  --iwrite"
        "--msi   --iread"
        "--msi   --iwrite"
    )
    takes_ary_as_arg descTable[@] optsTable[@]
}
try_with_local_arys

akan bergema:

sli4-iread sli4-iwrite sli3-iread sli3-iwrite  
--msix  --iread --msix  --iwrite --msi   --iread --msi   --iwrite

Edit / catatan: (dari komentar di bawah)

  • descTabledan optsTablediteruskan sebagai nama dan diperluas dalam fungsi. Jadi tidak $diperlukan ketika diberikan sebagai parameter.
  • Perhatikan bahwa ini masih berfungsi bahkan dengan descTabledll yang ditentukan local, karena penduduk setempat terlihat oleh fungsi yang mereka panggil.
  • The !dalam ${!1}memperluas variabel arg 1.
  • declare -a hanya membuat array yang diindeks eksplisit, itu tidak sepenuhnya diperlukan.
Ken Bertelson
sumber
14
Satu hal yang perlu diperhatikan adalah bahwa jika array asli jarang, array dalam fungsi penerima tidak akan memiliki indeks yang sama.
Dijeda sampai pemberitahuan lebih lanjut.
13
Ini brilian, tetapi dapatkah Ken atau seseorang menjelaskan beberapa hal yang membingungkan saya tentang mengapa ini bekerja: 1 - Saya akan berpikir bahwa descTable dan optsTable harus diawali dengan $ ketika dilewatkan sebagai argumen fungsi. 2 - Pada baris pertama "take ...", mengapa deklarasi array eksplisit diperlukan? 3 - Dan apa fungsinya! maksud dalam ekspresi $ {! 1}, dan mengapa [@] tidak diperlukan atau bahkan diizinkan di sana? - Ini berfungsi, dan semua detail ini tampaknya diperlukan berdasarkan pengujian saya, tetapi saya ingin memahami alasannya!
Jan Hettich
8
1: descTable dan optsTable hanya disahkan sebagai nama, jadi tidak ada $, mereka akan diperluas hanya dalam fungsi yang disebut 2: tidak sepenuhnya yakin, tapi saya pikir itu tidak benar-benar diperlukan 3: the! digunakan karena parameter yang diteruskan ke fungsi perlu diperluas dua kali: $ 1 berkembang menjadi "descTable [@]", dan itu harus diperluas ke "$ {descTable [@]}". Sintaks $ {! 1} melakukan hal ini.
Elmar Zander
8
Saya tidak berpikir bagian "mendeklarasikan -a" diperlukan. Keberadaan tanda kurung sudah mendefinisikan LHS dari penugasan sebagai sebuah array.
Erik Aronesty
3
Jawaban ini membantu saya memecahkan masalah sekarang. Namun, saya ingin menunjukkan bahwa di komputer saya (menggunakan bash 4.3.42) "$ {! 1}" dan "$ {! 2}" harus menghapus tanda kutip. Jika tidak, nilai array asli dibaca sebagai satu string dan ditugaskan ke argAry1 [0] dan argAry2 [0] masing-masing, pada dasarnya berarti struktur array hilang.
user.friendly
85

Catatan: Ini adalah solusi yang agak kasar yang saya posting sendiri, setelah tidak menemukan jawaban di Stack Overflow. Ini memungkinkan hanya satu array yang diteruskan, dan itu menjadi elemen terakhir dari daftar parameter. Sebenarnya, ia tidak melewatkan array sama sekali, tetapi daftar elemen-elemennya, yang dirakit kembali menjadi array dengan dipanggil_fungsi (), tetapi berhasil bagi saya. Agak kemudian Ken memposting solusinya, tetapi saya menyimpan milik saya di sini untuk referensi "bersejarah".

calling_function()
{
    variable="a"
    array=( "x", "y", "z" )
    called_function "${variable}" "${array[@]}"
}

called_function()
{
    local_variable="${1}"
    shift
    local_array=("${@}")
}

Ditingkatkan oleh TheBonsai, terima kasih.

DevSolar
sumber
19
Tiga tahun setelah fakta, jawaban ini - disimpan hanya karena alasan historis - menerima dua downvotes dalam beberapa hari. Seperti biasa pada SO, tanpa ada catatan mengapa orang berpikir ini dibenarkan. Perhatikan bahwa jawaban ini mendahului semua yang lain, dan bahwa saya menerima jawaban Ken sebagai solusi terbaik. Saya sangat sadar itu tidak sempurna, tetapi selama empat bulan itu yang terbaik tersedia di SO. Mengapa itu harus dibatalkan dua tahun setelah mengambil tempat kedua untuk solusi sempurna Ken adalah di luar saya.
DevSolar
@geirha: Saya akan meminta Anda untuk memeriksa siapa yang memposting pertanyaan, siapa yang memposting jawaban ini, dan siapa yang mungkin menerima jawaban yang Anda panggil "buruk". ;-) Anda mungkin juga ingin memeriksa Catatan dalam pertanyaan, yang menunjukkan mengapa solusi ini lebih rendah daripada Ken.
DevSolar
2
Saya tahu Anda mengajukan pertanyaan, Anda menulis jawaban ini, dan Anda menerima jawaban yang buruk. Itu sebabnya saya mengatakannya seperti itu. Alasan mengapa jawaban yang diterima buruk adalah karena ia mencoba untuk melewati array dengan referensi, yang merupakan sesuatu yang harus Anda hindari. Selain itu, contoh ini memadatkan banyak argumen menjadi satu string. Jika Anda benar-benar harus melewati array dengan referensi, bash adalah bahasa yang salah untuk memulai. Bahkan dengan variabel nameref baru bash 4.3, Anda tidak dapat menghindari tabrakan nama (referensi melingkar) dengan aman.
geirha
4
Nah, Anda bisa melewati beberapa array jika Anda memasukkan jumlah elemen dari setiap array. called_function "${#array[@]}" "${array[@]}" "${#array2[@]}" "${array2[@]}"dll ... masih dengan beberapa batasan yang jelas, tetapi benar-benar, lebih baik untuk menyelesaikan masalah dengan cara yang didukung bahasa, daripada mencoba membengkokkan bahasa agar berfungsi seperti yang biasa Anda lakukan dalam bahasa lain.
geirha
1
@geirha: Ya, saya kira kita harus setuju bahwa kita tidak setuju, dan Anda harus membiarkan saya menjadi hakim yang menjawab pertanyaan saya dengan jawaban terbaik. Secara pribadi, saya lebih memilih melewati array dengan referensi pula (tidak peduli bahasa, untuk menyimpan data menyalin); terlebih lagi ketika alternatifnya adalah menekuk ke belakang dan melewati ukuran array sebagai parameter tambahan ...
DevSolar
38

Mengomentari solusi Ken Bertelson dan menjawab Jan Hettich:

Bagaimana itu bekerja

fungsi takes_ary_as_arg descTable[@] optsTable[@]baris try_with_local_arys()mengirimkan:

  1. Ini sebenarnya membuat salinan dari array descTabledan optsTableyang dapat diakses oleh takes_ary_as_argfungsi.
  2. takes_ary_as_arg()fungsi menerima descTable[@]dan optsTable[@]sebagai string, itu berarti $1 == descTable[@]dan $2 == optsTable[@].
  3. di awal takes_ary_as_arg()fungsi menggunakan ${!parameter}sintaks, yang disebut referensi tidak langsung atau kadang-kadang dua direferensikan , ini berarti bahwa alih-alih menggunakan $1's nilai, kita menggunakan nilai diperluas nilai$1 , misalnya:

    baba=booba
    variable=baba
    echo ${variable} # baba
    echo ${!variable} # booba
    

    begitu juga untuk $2.

  4. menempatkan ini dalam argAry1=("${!1}")menciptakan argAry1sebagai array (tanda kurung =) dengan diperluas descTable[@], seperti menulis di sana argAry1=("${descTable[@]}")secara langsung. di declaresana tidak diperlukan.

NB: Perlu disebutkan bahwa inisialisasi array menggunakan bentuk braket ini menginisialisasi array baru sesuai dengan IFSatau Pemisah Bidang Internal yang secara default tab , baris baru dan ruang . dalam hal itu, karena [@]notasi yang digunakan masing-masing elemen dilihat dengan sendirinya seolah-olah ia dikutip (bertentangan dengan [*]).

Reservasi saya dengan itu

Dalam BASH, ruang lingkup variabel lokal adalah fungsi saat ini dan setiap fungsi anak dipanggil darinya, ini berarti fakta bahwa takes_ary_as_arg()fungsi "melihat" mereka descTable[@]dan optsTable[@]array, sehingga berfungsi (lihat penjelasan di atas).

Karena itu, mengapa tidak langsung melihat variabel-variabel itu sendiri? Sama seperti menulis di sana:

argAry1=("${descTable[@]}")

Lihat penjelasan di atas, yang hanya menyalin descTable[@]nilai array menurut arus IFS.

Singkatnya

Ini pada dasarnya tidak ada artinya - seperti biasa.

Saya juga ingin menekankan komentar Dennis Williamson di atas: array jarang (array tanpa semua kunci mendefinisikan - dengan "lubang" di dalamnya) tidak akan berfungsi seperti yang diharapkan - kita akan kehilangan kunci dan "menyingkat" array.

Yang sedang berkata, saya memang melihat nilai untuk generalisasi, fungsi sehingga bisa mendapatkan array (atau salinan) tanpa mengetahui nama-nama:

  • untuk ~ "salinan": teknik ini cukup baik, hanya perlu tetap waspada, bahwa indeks (kunci) hilang.
  • untuk salinan asli: kita dapat menggunakan eval untuk kunci, misalnya:

    eval local keys=(\${!$1})

dan kemudian loop menggunakannya untuk membuat salinan. Catatan: di sini !tidak digunakan sebelumnya tidak langsung / evaluasi ganda, melainkan dalam konteks array mengembalikan indeks array (kunci).

  • dan, tentu saja, jika kita harus lulus descTabledan optsTablestring (tanpa [@]), kita bisa menggunakan array itu sendiri (seperti dalam referensi) dengan eval. untuk fungsi generik yang menerima array.
Penyihir
sumber
2
Penjelasan yang bagus tentang mekanisme di balik penjelasan Ken Bertelson. Untuk pertanyaan "Menjadi kasus itu, mengapa tidak melihat langsung variabel-variabel itu sendiri?", Saya akan menjawab: hanya untuk penggunaan kembali fungsi. Katakanlah saya perlu memanggil fungsi dengan Array1, lalu dengan Array2, melewati nama array menjadi berguna.
gfrigon
Jawaban bagus, kita perlu penjelasan lebih lanjut seperti ini!
Édouard Lopez
22

Masalah mendasar di sini adalah bahwa pengembang bash (s) yang mendesain / mengimplementasikan array benar-benar mengacaukan anjing tersebut. Mereka memutuskan ${array}itu hanya ulah ${array[0]}, yang merupakan kesalahan buruk. Terutama ketika Anda menganggap itu ${array[0]}tidak memiliki arti dan mengevaluasi ke string kosong jika tipe array asosiatif.

Menetapkan array mengambil bentuk di array=(value1 ... valueN)mana nilai memiliki sintaks [subscript]=string, sehingga menetapkan nilai langsung ke indeks tertentu dalam array. Ini membuatnya jadi bisa ada dua jenis array, diindeks secara numerik dan hash diindeks (disebut asosiatif array dalam bahasa bash). Itu juga membuatnya sehingga Anda dapat membuat array diindeks numerik jarang. Meninggalkan [subscript]=bagian adalah tangan pendek untuk array yang diindeks secara numerik, dimulai dengan indeks ordinal 0 dan bertambah dengan setiap nilai baru dalam pernyataan penugasan.

Karena itu, ${array}harus mengevaluasi ke seluruh array, indeks, dan semua. Ini harus mengevaluasi kebalikan dari pernyataan penugasan. Setiap tahun ketiga CS mayor harus tahu itu. Dalam hal ini, kode ini akan berfungsi persis seperti yang Anda harapkan:

declare -A foo bar
foo=${bar}

Kemudian, meneruskan array dengan nilai ke fungsi dan menugaskan satu array ke array yang lain akan berfungsi sebagai perintah shell lainnya. Tetapi karena mereka tidak melakukan ini dengan benar, operator penugasan =tidak bekerja untuk array, dan array tidak dapat diteruskan oleh nilai ke fungsi atau ke subshell atau output secara umum ( echo ${array}) tanpa kode untuk mengunyah semuanya.

Jadi, jika itu dilakukan dengan benar, maka contoh berikut akan menunjukkan bagaimana kegunaan array di bash bisa jauh lebih baik:

simple=(first=one second=2 third=3)
echo ${simple}

output yang dihasilkan harus:

(first=one second=2 third=3)

Kemudian, array dapat menggunakan operator penugasan, dan diteruskan oleh nilai ke fungsi dan bahkan skrip shell lainnya. Mudah disimpan dengan mengeluarkan ke file, dan dengan mudah dimuat dari file ke dalam skrip.

declare -A foo
read foo <file

Sayangnya, kami telah dikecewakan oleh tim pengembang pesta superlatif.

Dengan demikian, untuk meneruskan array ke suatu fungsi, sebenarnya hanya ada satu opsi, dan itu adalah menggunakan fitur nameref:

function funky() {
    local -n ARR

    ARR=$1
    echo "indexes: ${!ARR[@]}"
    echo "values: ${ARR[@]}"
}

declare -A HASH

HASH=([foo]=bar [zoom]=fast)
funky HASH # notice that I'm just passing the word 'HASH' to the function

akan menghasilkan output berikut:

indexes: foo zoom
values: bar fast

Karena ini lewat referensi, Anda juga dapat menetapkan ke array dalam fungsi. Ya, array yang direferensikan harus memiliki cakupan global, tetapi itu tidak boleh terlalu besar, mengingat ini adalah skrip shell. Untuk meneruskan array indeks asosiatif atau jarang menurut nilai ke suatu fungsi, perlu membuang semua indeks dan nilai ke daftar argumen (tidak terlalu berguna jika array besar) sebagai string tunggal seperti ini:

funky "${!array[*]}" "${array[*]}"

dan kemudian menulis banyak kode di dalam fungsi untuk memasang kembali array.

tigerand
sumber
1
Solusi menggunakan local -nlebih baik dan lebih terkini daripada jawaban yang diterima. Solusi ini juga akan berfungsi untuk variabel jenis apa pun. Contoh yang tercantum dalam jawaban ini dapat disingkat menjadi local -n ARR=${1}. Namun -nopsi untuk local/ declarehanya tersedia di Bash versi 4.3 dan di atasnya.
richardjsimkins
Ini bagus! Gotcha kecil: jika Anda mengoper variabel dengan nama yang sama dengan argumen lokal fungsi Anda (misal funky ARR), shell akan memberikan peringatan circular name reference, karena pada dasarnya fungsi akan mencoba melakukannya local -n ARR=ARR. Diskusi yang bagus tentang topik ini.
Gene Pavlovsky
5

Jawaban DevSolar memiliki satu poin yang saya tidak mengerti (mungkin dia memiliki alasan khusus untuk melakukannya, tetapi saya tidak dapat memikirkannya): Dia mengatur array dari elemen parameter posisi dengan elemen, berulang.

Pendekatan yang lebih mudah adalah

called_function()
{
  ...
  # do everything like shown by DevSolar
  ...

  # now get a copy of the positional parameters
  local_array=("$@")
  ...
}
TheBonsai
sumber
1
Alasan saya untuk tidak melakukannya adalah karena saya belum bermain-main dengan array bash sama sekali sampai beberapa hari yang lalu. Sebelumnya saya akan beralih ke Perl jika menjadi kompleks, opsi yang tidak saya miliki di pekerjaan saya saat ini. Terima kasih atas petunjuknya!
DevSolar
3
function aecho {
  set "$1[$2]"
  echo "${!1}"
}

Contoh

$ foo=(dog cat bird)

$ aecho foo 1
cat
Steven Penny
sumber
3

Cara mudah untuk melewatkan beberapa array sebagai parameter adalah dengan menggunakan string yang dipisahkan karakter. Anda dapat memanggil skrip Anda seperti ini:

./myScript.sh "value1;value2;value3" "somethingElse" "value4;value5" "anotherOne"

Kemudian, Anda dapat mengekstraknya dalam kode Anda seperti ini:

myArray=$1
IFS=';' read -a myArray <<< "$myArray"

myOtherArray=$3
IFS=';' read -a myOtherArray <<< "$myOtherArray"

Dengan cara ini, Anda dapat benar-benar melewati beberapa larik sebagai parameter dan tidak harus menjadi parameter terakhir.

Remy Cilia
sumber
1

Ini berfungsi bahkan dengan spasi:

format="\t%2s - %s\n"

function doAction
{
  local_array=("$@")
  for (( i = 0 ; i < ${#local_array[@]} ; i++ ))
    do
      printf "${format}" $i "${local_array[$i]}"
  done
  echo -n "Choose: "
  option=""
  read -n1 option
  echo ${local_array[option]}
  return
}

#the call:
doAction "${tools[@]}"
kerang Sapiens
sumber
2
Saya ingin tahu apa intinya di sini. Ini hanya argumen biasa yang lewat. Sintaks "$ @" dibuat berfungsi untuk spasi: "$ @" setara dengan "$ 1" "$ 2" ...
Andreas Spindler
Bisakah saya meneruskan 2 array ke suatu fungsi?
pihentagy
1

Dengan beberapa trik, Anda dapat benar-benar mengirimkan parameter bernama ke fungsi, bersama dengan array.

Metode yang saya kembangkan memungkinkan Anda untuk mengakses parameter yang dikirimkan ke fungsi seperti ini:

testPassingParams() {

    @var hello
    l=4 @array anArrayWithFourElements
    l=2 @array anotherArrayWithTwo
    @var anotherSingle
    @reference table   # references only work in bash >=4.3
    @params anArrayOfVariedSize

    test "$hello" = "$1" && echo correct
    #
    test "${anArrayWithFourElements[0]}" = "$2" && echo correct
    test "${anArrayWithFourElements[1]}" = "$3" && echo correct
    test "${anArrayWithFourElements[2]}" = "$4" && echo correct
    # etc...
    #
    test "${anotherArrayWithTwo[0]}" = "$6" && echo correct
    test "${anotherArrayWithTwo[1]}" = "$7" && echo correct
    #
    test "$anotherSingle" = "$8" && echo correct
    #
    test "${table[test]}" = "works"
    table[inside]="adding a new value"
    #
    # I'm using * just in this example:
    test "${anArrayOfVariedSize[*]}" = "${*:10}" && echo correct
}

fourElements=( a1 a2 "a3 with spaces" a4 )
twoElements=( b1 b2 )
declare -A assocArray
assocArray[test]="works"

testPassingParams "first" "${fourElements[@]}" "${twoElements[@]}" "single with spaces" assocArray "and more... " "even more..."

test "${assocArray[inside]}" = "adding a new value"

Dengan kata lain, tidak hanya Anda dapat memanggil parameter Anda dengan nama mereka (yang merupakan inti yang lebih mudah dibaca), Anda sebenarnya dapat melewatkan array (dan referensi ke variabel - fitur ini hanya bekerja di bash 4.3)! Plus, variabel yang dipetakan semuanya dalam lingkup lokal, sama seperti $ 1 (dan lainnya).

Kode yang membuat pekerjaan ini cukup ringan dan berfungsi baik di bash 3 dan bash 4 (ini adalah satu-satunya versi yang telah saya uji dengan). Jika Anda tertarik dengan lebih banyak trik seperti ini yang membuat pengembangan dengan bash jauh lebih baik dan lebih mudah, Anda dapat melihat pada Bash Infinity Framework saya , kode di bawah ini dikembangkan untuk tujuan itu.

Function.AssignParamLocally() {
    local commandWithArgs=( $1 )
    local command="${commandWithArgs[0]}"

    shift

    if [[ "$command" == "trap" || "$command" == "l="* || "$command" == "_type="* ]]
    then
        paramNo+=-1
        return 0
    fi

    if [[ "$command" != "local" ]]
    then
        assignNormalCodeStarted=true
    fi

    local varDeclaration="${commandWithArgs[1]}"
    if [[ $varDeclaration == '-n' ]]
    then
        varDeclaration="${commandWithArgs[2]}"
    fi
    local varName="${varDeclaration%%=*}"

    # var value is only important if making an object later on from it
    local varValue="${varDeclaration#*=}"

    if [[ ! -z $assignVarType ]]
    then
        local previousParamNo=$(expr $paramNo - 1)

        if [[ "$assignVarType" == "array" ]]
        then
            # passing array:
            execute="$assignVarName=( \"\${@:$previousParamNo:$assignArrLength}\" )"
            eval "$execute"
            paramNo+=$(expr $assignArrLength - 1)

            unset assignArrLength
        elif [[ "$assignVarType" == "params" ]]
        then
            execute="$assignVarName=( \"\${@:$previousParamNo}\" )"
            eval "$execute"
        elif [[ "$assignVarType" == "reference" ]]
        then
            execute="$assignVarName=\"\$$previousParamNo\""
            eval "$execute"
        elif [[ ! -z "${!previousParamNo}" ]]
        then
            execute="$assignVarName=\"\$$previousParamNo\""
            eval "$execute"
        fi
    fi

    assignVarType="$__capture_type"
    assignVarName="$varName"
    assignArrLength="$__capture_arrLength"
}

Function.CaptureParams() {
    __capture_type="$_type"
    __capture_arrLength="$l"
}

alias @trapAssign='Function.CaptureParams; trap "declare -i \"paramNo+=1\"; Function.AssignParamLocally \"\$BASH_COMMAND\" \"\$@\"; [[ \$assignNormalCodeStarted = true ]] && trap - DEBUG && unset assignVarType && unset assignVarName && unset assignNormalCodeStarted && unset paramNo" DEBUG; '
alias @param='@trapAssign local'
alias @reference='_type=reference @trapAssign local -n'
alias @var='_type=var @param'
alias @params='_type=params @param'
alias @array='_type=array @param'
niieani
sumber
1

Hanya untuk menambah jawaban yang diterima, karena saya menemukan itu tidak berfungsi dengan baik jika isi arraynya seperti:

RUN_COMMANDS=(
  "command1 param1... paramN"
  "command2 param1... paramN"
)

Dalam hal ini, setiap anggota array akan terpecah, sehingga array yang dilihat fungsinya setara dengan:

RUN_COMMANDS=(
    "command1"
    "param1"
     ...
    "command2"
    ...
)

Agar case ini berfungsi, cara yang saya temukan adalah dengan meneruskan nama variabel ke fungsi, lalu gunakan eval:

function () {
    eval 'COMMANDS=( "${'"$1"'[@]}" )'
    for COMMAND in "${COMMANDS[@]}"; do
        echo $COMMAND
    done
}

function RUN_COMMANDS

Hanya 2 © saya

AlvaroGMJ
sumber
1

Seburuk itu, berikut adalah solusi yang berfungsi selama Anda tidak melewatkan array secara eksplisit, tetapi variabel yang sesuai dengan array:

function passarray()
{
    eval array_internally=("$(echo '${'$1'[@]}')")
    # access array now via array_internally
    echo "${array_internally[@]}"
    #...
}

array=(0 1 2 3 4 5)
passarray array # echo's (0 1 2 3 4 5) as expected

Saya yakin seseorang dapat datang dengan implementasi ide yang lebih jelas, tetapi saya telah menemukan ini menjadi solusi yang lebih baik daripada melewati array "{array[@]"}dan kemudian mengaksesnya menggunakan internal array_inside=("$@"). Ini menjadi rumit ketika ada posisi / getoptsparameter lain. Dalam kasus ini, saya harus terlebih dahulu menentukan dan kemudian menghapus parameter yang tidak terkait dengan array menggunakan beberapa kombinasi shiftdan penghapusan elemen array.

Perspektif murni cenderung memandang pendekatan ini sebagai pelanggaran bahasa, tetapi secara pragmatis, pendekatan ini telah menyelamatkan saya dari banyak kesedihan. Pada topik terkait, saya juga menggunakan evaluntuk menetapkan array yang dibangun secara internal ke variabel bernama sesuai dengan parameter yang target_varnamesaya berikan ke fungsi:

eval $target_varname=$"(${array_inside[@]})"

Semoga ini bisa membantu seseorang.

Blake Schultze
sumber
0

Persyaratan : Berfungsi untuk menemukan string dalam array.
Ini adalah sedikit penyederhanaan dari solusi DevSolar karena menggunakan argumen yang disahkan daripada menyalinnya.

myarray=('foobar' 'foxbat')

function isInArray() {
  local item=$1
  shift
  for one in $@; do
    if [ $one = $item ]; then
      return 0   # found
    fi
  done
  return 1       # not found
}

var='foobar'
if isInArray $var ${myarray[@]}; then
  echo "$var found in array"
else
  echo "$var not found in array"
fi 
Andre
sumber
0

Jawaban singkat saya adalah:

function display_two_array {
    local arr1=$1
    local arr2=$2
    for i in $arr1
    do
       "arrary1: $i"
    done
    
    for i in $arr2
    do
       "arrary2: $i"
    done
}

test_array=(1 2 3 4 5)
test_array2=(7 8 9 10 11)

display_two_array "${test_array[*]}" "${test_array2[*]}"
Perlu diperhatikan bahwa ${test_array[*]}dan ${test_array2[*]}harus dikelilingi oleh "", jika tidak Anda akan gagal.

untukku
sumber
Contoh Anda salah karena tidak lengkap. Tolong beri kode lengkap skrip.
Dennis VR