Bash не равнозначное сравнение строк

Bash не равнозначное сравнение строк

Почему это приводит к бесконечному циклу?

#!/bin/bash
while [[ "$(ipcs | awk '{print $2}')" != "Semaphore" ]]; do
  #Gonna get rid of the echo after working
  echo "$(ipcs | awk '{print $2}')"
  #I want to keep this
  ipcrm shm "$(ipcs | awk '{print $2}')"
  #I want this run after breaking out of the loop until I reach the string
  #Message. 
  ipcrm -s "$(ipcs | awk '{print $2}')"
done      
echo
exit 0

Я проверил, что в конечном итоге получаю Semaphore, поэтому он должен выйти из цикла while.

$ echo $(ipcs | awk '{print $2}')
Shared shmid 262145 294914 2326531 Semaphore semid Message msqid


$ ipcs

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x00000000 262145     bob        600        393216     2          dest         
0x00000000 294914     bob        600        393216     2          dest         
0x00000000 2490371    bob        600        998400     2          dest         

------ Semaphore Arrays --------
key        semid      owner      perms      nsems     

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    

$ echo $(ipcs |  awk '{print $1}')
------ key 0x00000000 0x00000000 0x00000000 ------ key ------ key

$ echo $(ipcs |  awk '{print $2}')
Shared shmid 262145 294914 2490371 Semaphore semid Message msqid

решение1

$(ipcs | awk '{print $2}')никогда не равно Semaphore. Оно всегда равно:

Shared shmid 262145 294914 2326531 Semaphore semid Message msqid

Вероятно, вы хотите что-то вроде:

for e in $(ipcs | awk '{print $2}'); do
    [[ "$e" = "Semaphore" ]] && break
    echo $e
done

echo
exit 0

Вам также может понравиться это awkрешение:

ipcs | awk '$2 == "Semaphore" {exit;} $2 != "" {print $2}'

Небольшое пояснение:

  • Если второе полеСемафор, Выход.
  • В противном случае, если это поле не пустое, распечатайте его.

Вот несколько альтернативных решений (предполагая, что я понял ваши потребности):

# List all shared memory segments keys
ipcs -m | awk 'NR > 3 && $1 != "" {print $1}'

# List all shared memory segments IDs
ipcs -m | awk 'NR > 3 && $2 != "" {print $2}'

Для каждого из этих примеров вы можете выполнить итерацию по результату:

for e in $(above command); do
    echo $e
done

решение2

Вот немного другой способ реализации цикла while:

$ while read line; do 
    echo "$line"; 
    if [[ "$line" != *Semaphore* ]]; then 
        echo "not semaphore"; 
    else 
        echo "is semaphore"; 
    fi;
  done < <(ipcs | awk '{print $2}')

Что дает следующий результат:

...
not semaphore
814972976
not semaphore
815005745
not semaphore
817070167
not semaphore

not semaphore
Semaphore
is semaphore
semid
not semaphore

Обратите внимание, что когда он доходит до строки «Семафор», он правильно ее идентифицирует.

Связанный контент