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

문자열 "Semaphore"에 도달하면 이를 올바르게 식별합니다.

관련 정보