Dizilerin bash'de parametre olarak iletilmesi


188

Bir diziyi bash işlevine parametre olarak nasıl iletebilirim?

Not: Burada Stack Overflow'da bir cevap bulamadım, biraz kaba çözümümü kendim yayınladım. Sadece bir dizi geçirilmesine izin verir ve parametre listesinin son elemanıdır. Aslında, diziyi hiç geçmiyor, ancak call_function () ile bir diziye yeniden birleştirilen öğelerinin bir listesi, ama benim için çalıştı. Birisi daha iyi bir yol biliyorsa, buraya eklemekten çekinmeyin.


1
Burada güzel bir referans ve tonlarca örnek var.
Artem Barger

16
Errr ... Aynı dakika içinde beş yaşındaki bir soruya üç iniş?
DevSolar

Yanıtlar:


220

Bunun gibi bir şey kullanarak bağımsız değişkenler olarak birden çok dizi geçirebilirsiniz :

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

yankılanacak:

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

Düzenleme / notlar: (aşağıdaki yorumlardan)

  • descTableve optsTableadlar olarak iletilir ve işlevde genişletilir. Bu nedenle $parametre olarak verildiğinde hiçbir şeye gerek yoktur .
  • Yerel halkın aradıkları işlevler tarafından görülebildiği için, descTablebunun tanımlanmış vb. İle bile çalıştığını unutmayın local.
  • !İçerisinde ${!1}Arg 1 değişkeni genişler.
  • declare -a sadece dizine alınan diziyi açık yapar, kesinlikle gerekli değildir.

14
Dikkat edilmesi gereken bir nokta, orijinal dizi seyrek ise, alıcı fonksiyondaki dizinin aynı indekslere sahip olmamasıdır.
sonraki duyuruya kadar duraklatıldı.

13
Bu harika, ama Ken ya da birisi neden işe yaradığına dair beni şaşırtan birkaç şeyi açıklayabilir mi: 1 - descTable ve optsTable'ın işlev argümanları olarak iletildiğinde $ ile ön ekinin olması gerektiğini düşünürdüm. 2 - "Alır ..." ın ilk satırında neden açık bir dizi bildirimi gerekiyor? 3 - Ve ne yapıyor! $! - Bu işe yarıyor ve testlerime dayanarak tüm bu detaylara ihtiyaç var gibi görünüyor, ama nedenini anlamak istiyorum!
Jan Hettich

8
1: descTable ve optsTable sadece isimler olarak geçirilir, bu yüzden $ yoktur, sadece çağrılan fonksiyonda genişletilirler 2: tamamen emin değilim, ama gerçekten gerekli olmadığını düşünüyorum 3: the! , işleve iletilen parametrelerin iki kez genişletilmesi gerektiğinden kullanılır: $ 1, "descTable [@]" olarak genişler ve bunun "$ {descTable [@]}" olarak genişletilmesi gerekir. $ {! 1} sözdizimi sadece bunu yapar.
Elmar Zander

8
"Declare -a" kısmının gerekli olduğunu düşünmüyorum. Parantezin varlığı ödevin LHS'sini zaten bir dizi olarak tanımlar.
Erik Aronesty

3
Bu cevap şimdi bir sorunu çözmeme yardımcı oldu. Ancak, makinemde (bash 4.3.42 kullanarak) "$ {! 1}" ve "$ {! 2}" nin tırnak işaretleri kaldırılması gerektiğini belirtmek istedim. Bunu yapmazsanız, orijinal dizinin değeri bir dize olarak okunur ve sırasıyla argAry1 [0] ve argAry2 [0] 'a atanır, temelde dizi yapısı kaybolur.
user.friendly

85

Not: Bu, Stack Overflow'da burada bir cevap bulamadım, kendime gönderdiğim biraz kaba bir çözüm. Sadece bir dizi geçirilmesine izin verir ve parametre listesinin son elemanıdır. Aslında, diziyi hiç geçmiyor, ancak call_function () ile bir diziye yeniden birleştirilen öğelerinin bir listesi, ama benim için çalıştı. Bir süre sonra Ken çözümünü yayınladı, ama benim "tarihi" referans için burada kaldım.

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

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

TheBonsai tarafından geliştirildi, teşekkürler.


19
Üç yıl sonra, sadece tarihsel nedenlerden ötürü tutulan bu cevap birkaç gün içinde iki downvotes aldı. Ne yazık ki SO'da olağan olduğu gibi, insanların bunun neden garanti edildiğine dair herhangi bir not olmadan. Bu cevabın diğerlerinden önce geldiğine ve Ken'in cevabını en iyi çözüm olarak kabul ettiğime dikkat edin. Ben mükemmel hiçbir yerde mükemmel olduğunu biliyorum, ama dört ay için SO mevcut en iyisiydi. Ken'in kusursuz çözümüne ikinci sırada yer almasından iki yıl sonra neden reddedilmem gerekiyor .
DevSolar

@geirha: Soruyu kimin gönderdiğini, bu cevabı kimin gönderdiğini ve muhtemelen "kötü" olarak adlandırdığınız cevabı kimin kabul ettiğini kontrol etmenizi isterim. ;-) Ayrıca , bu çözümün Ken'den daha düşük olduğuna dikkat çeken sorudaki Notu da kontrol etmek isteyebilirsiniz .
DevSolar

2
Soruyu sorduğunuzu biliyorum, bu cevabı yazdınız ve kötü cevabı kabul ettiğinizi. Bu yüzden bu şekilde ifade ettim. Kabul edilen cevabın kötü olmasının nedeni, diziyi referans olarak geçmeye çalışmasıdır, bu gerçekten kaçınmanız gereken bir şeydir. Ayrıca, örnek birden çok argümanı tek bir dizede birleştirir. Dizileri gerçekten referans olarak geçmeniz gerekiyorsa, bash başlamak için yanlış dildir. Bash 4.3'ün yeni nameref değişkenleriyle bile, ad çakışmalarını güvenli bir şekilde önleyemezsiniz (dairesel referans).
geirha

4
Her dizinin öğe sayısını eklerseniz, birden çok dizi geçirebilirsiniz. called_function "${#array[@]}" "${array[@]}" "${#array2[@]}" "${array2[@]}"vb ... yine de bazı bariz kısıtlamalar ile, ama gerçekten, dili diğer dillerde alıştığınız şekilde çalışmaya dönüştürmek yerine, dili desteklediği bir şekilde çözmek daha iyidir.
geirha

1
@geirha: Sanırım hemfikir olmadığımızı kabul etmemiz gerekecek ve hangi cevabın soruma en iyi cevap verdiğinin yargıcı olmama izin vermelisin. Şahsen ben zaten dizileri referans ile geçmeyi tercih ederim (dil olursa olsun, veri kopyasını kaydetmek için); alternatif daha geriye doğru eğmek ve dizi boyutunu ek parametre olarak geçirmek olduğunda ...
DevSolar

38

Ken Bertelson çözümünü yorumlamak ve Jan Hettich'e cevap vermek:

Nasıl çalışır

takes_ary_as_arg descTable[@] optsTable[@]hat try_with_local_arys()işlevi gönderir:

  1. Bu aslında bir kopyasını oluşturur descTableve optsTableerişebileceği diziler takes_ary_as_argfonksiyonu.
  2. takes_ary_as_arg()fonksiyon alır descTable[@]ve optsTable[@]dizeleri, o aracı olarak $1 == descTable[@]ve $2 == optsTable[@].
  3. takes_ary_as_arg()işlevin başlangıcında dolaylı başvuru veya bazen çift ​​başvuru${!parameter} olarak adlandırılan sözdizimini kullanır ; bu, 'değerini kullanmak yerine , örneğin genişletilmiş değerinin değerini kullandığımız anlamına gelir :$1$1

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

    aynı şekilde $2.

  4. bunu koymak , doğrudan orada yazmak gibi , genişletilmiş bir dizi (aşağıdaki parantezler ) olarak argAry1=("${!1}")oluşturur . Orada gerekli değildir.argAry1=descTable[@]argAry1=("${descTable[@]}")declare

Not: Bu parantez formunu kullanarak dizi başlatmanın yeni diziyi varsayılan sekme , satırsonu ve boşluk olan IFSveya Dahili Alan Ayırıcısına göre başlattığını belirtmek gerekir . bu durumda, gösterimi kullandığı için, her bir öğe kendi başına (sanki ) alıntılanmış gibi görülür .[@][*]

Rezervasyonum

Burada BASH, yerel değişken kapsam geçerli işlevdir ve ondan çağrılan her alt işlev, bu takes_ary_as_arg()işlevin bunları descTable[@]ve optsTable[@]dizileri "gördüğü" anlamına gelir , böylece çalışır (yukarıdaki açıklamaya bakın).

Bu durumda, neden bu değişkenlerin kendilerine doğrudan bakmıyorsunuz? Tıpkı oraya yazmak gibi:

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

Sadece descTable[@]dizinin değerlerini akıma göre kopyalayan yukarıdaki açıklamaya bakın IFS.

Özetle

Bu, özünde, değere göre hiçbir şeyden geçmiyor - her zamanki gibi.

Ayrıca yukarıdaki Dennis Williamson yorum vurgulamak istiyorum: seyrek diziler (tüm anahtarlar tanımlar - dizileri "delikleri ile diziler olmadan) beklendiği gibi çalışmaz - biz anahtarları kaybeder ve dizi yoğunlaştırmak.

Olduğu söyleniyor, ben genelleme için değer görüyorum, böylece fonksiyonları isimleri bilmeden dizileri (veya kopyaları) alabilirsiniz:

  • ~ "kopyalar" için: bu teknik yeterince iyidir, sadece farkında olmanız gerekir, indekslerin (anahtarlar) kaybolduğu.
  • gerçek kopyalar için: anahtarlar için bir eval kullanabiliriz, örneğin:

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

ve daha sonra kopya oluşturmak için bunları kullanan bir döngü. Not: Burada !önceki dolaylı / çift değerlendirme kullanılmaz, daha ziyade dizi bağlamında dizi indekslerini (anahtarlar) döndürür.

  • Biz geçmek olsaydı ve, tabii ki, descTableve optsTableşeritler (olmadan [@]), biz dizi kendisi (referans ile bu gibi) de kullanabilir eval. dizileri kabul eden genel bir işlev için.

2
Ken Bertelson'un arkasındaki mekanizmanın iyi açıklamaları. "Bu durumda, neden bu değişkenlerin kendilerine doğrudan bakmıyorsunuz?" Sorusuna, sadece işlevin yeniden kullanımı için cevap vereceğim. Diyelim ben bir işlevi çağırmak gerekir demek Array1olan, daha sonra Array2kullanışlı hale dizi isimlerini geçirerek,.
Mart'ta gfrigon

Harika cevap, bunun gibi daha fazla açıklamaya ihtiyacımız var!
Edouard Lopez

22

Buradaki temel sorun, dizileri tasarlayan / uygulayan bash geliştiricilerinin gerçekten pooch'u vidalamasıdır. Bunun ${array}sadece kısa el olduğuna karar verdiler ${array[0]}, bu kötü bir hataydı. Özellikle bunun bir ${array[0]}anlamı olmadığını düşündüğünüzde ve dizi türü ilişkiliyse boş dizeyi değerlendirdiğinde.

Bir dizi atamak, değerin array=(value1 ... valueN)sözdizimine sahip olduğu formu alır [subscript]=string, böylece doğrudan dizideki belirli bir dizine bir değer atar. Bu, sayısal olarak indekslenmiş ve karma indekslenmiş iki tür dizi olabilmesini sağlar (bash ilişkisinde ilişkilendirilebilir diziler olarak adlandırılır). Ayrıca, sayısal olarak dizinlenmiş seyrek diziler oluşturabilmenizi sağlar. Parçayı bırakmak [subscript]=sayısal sıralı bir dizi için kısa eldir, sıra sıra 0'dan başlayarak ve atama deyimindeki her yeni değerle birlikte artar.

Bu nedenle, ${array}için değerlendirmelidir tüm dizi, endeksler ve tüm. Atama ifadesinin tersini değerlendirmelidir. Herhangi bir üçüncü yıl CS büyük bilmeli. Bu durumda, bu kod tam olarak beklediğiniz gibi çalışır:

declare -A foo bar
foo=${bar}

Daha sonra, işlevlere değerlere göre diziler iletmek ve bir diziyi diğerine atamak, kabuk sözdiziminin geri kalanı belirlediği gibi çalışır. Ancak bunu doğru yapmadıkları için, atama operatörü =diziler için çalışmaz ve diziler, echo ${array}her şeyi çiğnemek için kod olmadan işlevlere veya alt kabuklara veya genel olarak ( ) değere göre geçirilemez .

Dolayısıyla, eğer doğru bir şekilde yapılmış olsaydı, aşağıdaki örnek, dizideki dizilerin kullanışlılığının nasıl daha iyi olabileceğini gösterecektir:

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

elde edilen çıktı şu şekilde olmalıdır:

(first=one second=2 third=3)

Daha sonra, diziler atama işlecini kullanabilir ve işlevlere ve hatta diğer kabuk komut dosyalarına değere göre geçirilebilir. Bir dosyaya çıktı vererek kolayca saklanır ve bir dosyadan bir betiğe kolayca yüklenir.

declare -A foo
read foo <file

Ne yazık ki, başka türlü üstün bir bash geliştirme ekibi tarafından hayal kırıklığına uğradık.

Bu nedenle, bir diziyi bir işleve geçirmek için gerçekten tek bir seçenek vardır ve bu nameref özelliğini kullanmaktır:

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

aşağıdaki çıktı ile sonuçlanacaktır:

indexes: foo zoom
values: bar fast

Bu referans olarak geçtiği için işlevdeki diziye de atayabilirsiniz. Evet, başvurulan dizinin genel bir kapsamı olmalıdır, ancak bunun kabuk komut dosyası olduğu düşünülürse çok büyük bir anlaşma olmamalıdır. Bir işleve ilişkisel veya seyrek dizine alınmış bir diziyi değere göre geçirmek için, tüm dizinleri ve değerleri bağımsız değişken listesine (büyük bir dizi ise çok yararlı değildir) aşağıdaki gibi tek dizeler olarak atmak gerekir:

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

ve sonra diziyi yeniden birleştirmek için işlevin içine bir grup kod yazmak.


1
Kullanmanın çözümü local -n, kabul edilen cevaptan daha iyi ve günceldir. Bu çözüm aynı zamanda her tür değişken için de işe yarayacaktır. Bu cevapta listelenen örnek kısaltılabilir local -n ARR=${1}. Ancak / -nseçeneği yalnızca Bash sürüm 4.3 ve üstü için geçerlidir. localdeclare
richardjsimkins

Bu güzel! Küçük gotcha: Eğer fonksiyonunuzun yerel argümanıyla aynı ada sahip bir değişken iletirseniz (örneğin funky ARR), kabuk uyarı verecektir circular name reference, çünkü temelde fonksiyon yapmaya çalışacaktır local -n ARR=ARR. Bu konu hakkında iyi tartışma .
Gene Pavlovsky

5

DevSolar'ın cevabı anlamadığım bir noktaya sahip (belki de bunu yapmak için özel bir nedeni var, ama bir tane düşünemiyorum): Diziyi konumsal parametrelerden eleman, yinelemeli olarak ayarlar.

Daha kolay bir yaklaşım

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

  # now get a copy of the positional parameters
  local_array=("$@")
  ...
}

1
Bunu yapmama nedenim, birkaç gün öncesine kadar bash dizileriyle oynamadığım. Önceden karmaşık olsaydı Perl'e geçirdim, mevcut işimde olmayan bir seçenek. İpucu için teşekkürler!
DevSolar

3
function aecho {
  set "$1[$2]"
  echo "${!1}"
}

Misal

$ foo=(dog cat bird)

$ aecho foo 1
cat

3

Birkaç diziyi parametre olarak iletmenin kolay bir yolu, karakterle ayrılmış bir dize kullanmaktır. Senaryonuzu şöyle çağırabilirsiniz:

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

Ardından, kodunuzda şu şekilde ayıklayabilirsiniz:

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

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

Bu şekilde, aslında birden fazla diziyi parametre olarak iletebilirsiniz ve son parametre olması gerekmez.


1

Bu, boşluklarla bile çalışır:

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[@]}"

2
Merak ediyorum burada ne var. Bu sadece normal bir tartışma. "$ @" Sözdizimi, boşluklar için kullanılabilir: "$ @", "$ 1" "2 $" ile eşdeğerdir ...
Andreas Spindler

Bir işleve 2 diziyi aktarabilir miyim?
pihentagy

1

Birkaç hile ile adlandırılmış parametreleri fonksiyonlarla birlikte dizilere aktarabilirsiniz.

Geliştirdiğim yöntem, aşağıdaki gibi bir işleve iletilen parametrelere erişmenizi sağlar:

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"

Başka bir deyişle, parametrelerinizi isimlerine göre (daha okunabilir bir çekirdeği oluşturan) çağıramazsınız, aslında dizileri de geçirebilirsiniz (ve değişkenlere referanslar - bu özellik sadece bash 4.3'te çalışır)! Ayrıca, eşlenen değişkenlerin tümü yerel kapsamda, tıpkı 1 $ (ve diğerleri) gibi.

Bu işi yapan kod oldukça hafif ve hem bash 3 hem de bash 4'te çalışıyor (bunlar test ettiğim tek sürümler). Eğer bash ile geliştirmeyi daha güzel ve kolay hale getiren daha fazla hile ile ilgileniyorsanız, Bash Infinity Framework'üme bir göz atabilirsiniz , aşağıdaki kod bu amaç için geliştirilmiştir.

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'

1

Sadece kabul edilen cevaba eklemek için, bulduğum gibi dizi içeriği gibi bir şey varsa iyi çalışmıyor:

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

Bu durumda, dizinin her üyesi bölünür, böylece işlevin gördüğü dizi eşittir:

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

Bu vakanın işe yaramasını sağlamak için bulduğum yol değişken ismini işleve iletmek ve ardından eval kullanmaktır:

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

function RUN_COMMANDS

Sadece benim 2 ©


1

Oldukça çirkin olduğu gibi, bir diziyi açıkça geçmediğiniz sürece çalışan bir geçici çözüm, ancak bir diziye karşılık gelen bir değişken:

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

Eminim birileri fikrin daha net bir uygulaması ile gelebilir, ama ben bir dizi olarak geçip daha "{array[@]"}sonra dahili olarak kullanarak erişmek daha iyi bir çözüm olarak buldum array_inside=("$@"). Başka pozisyon / getoptsparametreler olduğunda bu karmaşık hale gelir . Bu durumlarda, önce bazı shiftdizi ve dizi öğesi kaldırma kullanarak dizi ile ilişkili olmayan parametreleri belirlemek ve kaldırmak zorunda kaldı .

Sade bir perspektif muhtemelen bu yaklaşımı dilin ihlali olarak görüyor, ancak pragmatik olarak, bu yaklaşım beni çok fazla kederden kurtardı. İlgili bir konuda, ben de işleve ilettiğim evalbir parametreye göre adlı bir değişkene dahili olarak oluşturulmuş bir dizi atamak için kullanın target_varname:

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

Umarım bu birine yardımcı olur.


0

Gereksinim : Bir dizide dize bulma işlevi.
Bu, DevSolar'ın çözümünü, kopyalamak yerine geçirilen argümanları kullanması nedeniyle hafif bir basitleştirmedir.

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 

0

Kısa cevabım:

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[*]}"
Fark edilmelidir ${test_array[*]}ve ${test_array2[*]}aksi takdirde başarısız olacak "" ile çevrili olmalıdır.


Örneğiniz yanlış olduğu için yanlış. Lütfen komut dosyasının tam kodunu verin.
Dennis VR
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.