Как сравнить значения из массива в сценарии оболочки?

avatar
Martin Cernak
8 августа 2021 в 19:47
65
1
0

Почему эти линии не работают? И можно ли заставить их работать? И можете ли вы объяснить мне, как оболочка считывает значения из массива, в виде текста или целых чисел, если это глупый вопрос, пожалуйста, не смейтесь, я только начал склоняться :).

if  [ ${a[1]} -gt ${a[2]} ] ;
for (( b=0; b > ${a[2]}; b++));
#!/bin/bash
read a arr


if [ ${a[0]} -ne 1 ] && [ ${a[0]} -ne 2 ] && [ ${a[0]} -ne 3 ];
 then
 echo "Ne poznam vrednosti prvega parametra"
 echo "Konec skripte"
 else  
  if [ ${a[0]} -eq 1 ];
   then
   echo "Prvi parameter ima vrednost ${a[0]}"
   if  [ ${a[1]} -gt ${a[2]} ] ; 
     then
      echo "Drugi parameter je vecji ali enak tretjemu parametru."
     else
      echo "Drugi parameter ni vecji ali enak tretjemu parametru."
    fi  
  fi
  if [ ${a[0]} -eq 2 ];
    then
      echo "Prvi parametar ima vrednost: 2"
      for (( b=0; b > ${a[2]}; b++));
      do 
       
       echo "WORKS"
       
      done              
  fi    
fi
Источник
Jetchisel
8 августа 2021 в 19:49
3

Вставьте свой скрипт на shellcheck.net для проверки/предложений.

markp-fuso
8 августа 2021 в 20:33
0

как вы думаете, что должен делать read a arr, особенно в свете всех ссылок на массив с именем a[]?

Martin Cernak
8 августа 2021 в 20:34
0

это позволяет мне вводить значения в терминале, например: 1 5 4

markp-fuso
8 августа 2021 в 20:36
0

конечно, но где хранятся эти значения? Я предполагаю, что вам нужно, это read -a arr ... для хранения этих значений (1 5 4) в массиве с именем arr[], но затем вам нужно исправить остальную часть кода, чтобы вместо ссылки на массив с именем a[] вы действительно хотите сослаться на массив с именем arr[]; в качестве альтернативы используйте read -a a для чтения значений в массив с именем a[], и нет необходимости изменять последующие ссылки на массив с именем a[]

markp-fuso
8 августа 2021 в 20:38
0

Между прочим, read a arr приведет к a=1 и arr='5 4', причем ни одна из переменных (a, arr) не будет массивом

Martin Cernak
8 августа 2021 в 20:41
0

но когда я изменяю его на read a a, он больше не читает его как массив

markp-fuso
8 августа 2021 в 20:43
0

read -a a (то, что я рекомендовал) — это не то же самое, что read a a (то, что вы пробовали); а исходный код (read a arr) был не для хранения чего-либо в массиве; заменить read a arr на unset a + <newline> + read -a a; unset a может быть излишним, но гарантирует, что read -a a создаст новый массив с именем a[]

Martin Cernak
8 августа 2021 в 20:47
0

Спасибо, чувак, я такой тупой. Теперь вы понимаете, почему мой цикл for не работает, он просто пропускает его.

markp-fuso
8 августа 2021 в 21:00
0

если ваш ввод (в read) равен 1 5 4, то ваш массив выглядит так: a[0]="1" a[1]="5" a[2]="4", это, в свою очередь, означает, что if [ ${a[0]} -eq 2 ] является ложным (т. е. if [ 1 -eq 2 ] является ложным), и поэтому ваш код никогда не доходит до for, но даже если ваш код попадает в цикл for, он не сработает, потому что вы начинаете с b=0, а затем говорите запустить в то время как b > a[2], но <60211103787710> on, но <602111037 so8 первый запуск цикла for, который вы говорите запустить в то время как 0 > 4, что является ложным, поэтому цикл for никогда не выполняется

markp-fuso
8 августа 2021 в 21:05
0

в строке перед первым if добавьте set -xv, чтобы включить (после последнего fi добавьте set +xv, чтобы отключить) режим отладки, затем запустите сценарий и просмотрите выходные данные отладки, чтобы увидеть, какие значения обрабатываются каждым тест/команда

Martin Cernak
8 августа 2021 в 21:11
0

Хорошо, как мне заставить его работать? Если я ввожу 2 3 4, мне нужно, чтобы он печатал «работает» 4 раза. мне нужно, чтобы он печатался, пока b не достигнет 4 (a [2])

markp-fuso
8 августа 2021 в 21:29
0

Я уже указывал, что b > $a[2] говорит о запуске цикла for в то время как b больше, чем $a[2], но если вы начнете с $a[2], то вы указываете циклу for запустить в то время как 0 > 4, что никогда не бывает верным; оооооо, возможно, измените свой тест на ... idk ... возможно ... b <= ${a[2]} (так что для 1-го прохода 0 <= 4 верно, 2-го прохода 1 <= 4 верно, 3-го прохода 3 <= 4 верно, 4-го pass 4 <= 4 верно, 5-й проход 5 <= 4 ложно) ... ???

Martin Cernak
8 августа 2021 в 21:41
1

Спасибо, чувак, ты решил эту проблему для меня, я наконец-то могу закончить свой проект, я бы хотел не быть бедным, чтобы я мог заплатить тебе! Вы не только помогли мне, но и объяснили мне это, и я очень благодарен!

Ответы (1)

avatar
papanito
8 августа 2021 в 20:12
0

Я думаю, что первая проблема заключается в отсутствии пробела после [ и перед ].

И в огневом цикле второе выражение должно быть циклическим тестом или условием, которое ложно, поэтому цикл не будет выполнен. Может быть, это должно быть b <= ${a[2]}

См. https://www.cyberciti.biz/faq/bash-for-loop/ для некоторых примеров.