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

私はセマフォで終わることを確認したので、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}'

いくつかの説明:

  • 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

文字列「Sem​​aphore」に達すると、それを正しく識別します。

関連情報