Почему это приводит к бесконечному циклу?
#!/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
Обратите внимание, что когда он доходит до строки «Семафор», он правильно ее идентифицирует.