これは機能しますが、私がこれを実行した方法はちょっとばかげています。これを行うより良い方法はありますか?
for e in $(ipcs | awk '{print $2}'); do
[[ "$e" = "Semaphore" ]] && break
echo $e
ipcrm shm $e
done
echo $e outside for loop
for e in $(ipcs | awk '{print $2}'); do
[[ "$e" = "Message" ]] && break
echo $e
ipcrm -s $e
done
echo
exit 0
ipcs を実行したとき、次のような表示になります。
$ ipcs
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 262145 bob 600 393216 2 dest
0x00000000 2523138 bob 600 393216 2 dest
0x00000000 2555907 bob 600 393216 2 dest
0x00000000 3375108 bob 600 998400 2 dest
0x00000000 3440645 bob 666 40 1
------ Semaphore Arrays --------
key semid owner perms nsems
0x000005b1 262146 bob 600 6
------ Message Queues --------
key msqid owner perms used-bytes messages
これら 2 つのコマンドを定期的に実行する必要があります。
ipcrm -s $(ipcs | grep bob | awk '{printf "%s ",$2}')
ipcrm shm $(ipcs | grep bob | awk '{printf "%s ",$2}')
それで、私はこのようなことができるのではないかと考えました。
if [ `$(ipcs | grep Shared | awk '{print $2}')` == "Shared"]
ipcrm shm $(ipcs | grep bob | awk '{printf "%s ",$2}')
$2 が Semaphore に等しくなるまで、最初の動作を実行したいと思います。
if [ `$(ipcs | grep Semaphore | awk '{print $2}')` == "Semaphore"]
ipcrm -s $(ipcs | grep bob | awk '{printf "%s ",$2}'
まとめると、最初の if ブロックは「Shared」を確認した後に実行する必要があります。次に、2 番目の if ブロックは「Semaphore」を確認した後に実行する必要があります。
答え1
ipcrm shm <ids>
私の理解が正しければ、ユーザー bob のすべての共有メモリ セグメントに対してコマンドを実行したいということですね。次に、ipcrm -s <ids>
ユーザー bob のすべてのセマフォ配列に対してコマンドを実行します。
これを実現するには、次のコマンドを使用します (スクリプトをループする必要はありません)。
共有メモリセグメント部分の場合:
ipcrm shm $(ipcs -m | awk '$3=="bob" {printf "%s ",$2}')
セマフォ配列部分の場合:
ipcrm -s $(ipcs -s | awk '$3=="bob" {printf "%s ",$2}')
説明:
マンページからipcs
:
-m shared memory segments
-s semaphore arrays
このawk
部分は、3 番目のフィールドが bob の場合にのみ ID を出力します。
答え2
多分...
ipcs | sed -n '
s/[^ ]* *//
/^Messages/q
/^Semaphores/cshift
/ *bob .*/!d;s///
/ /!s/./ipcrm $1 &/p
'| sh -s -- shm \-s
文字列を含まない行を削除しますボブ3番目のスペースで区切られたフィールドとしてまたは2番目のフィールドにないメッセージ/セマフォ。
ipcrm $1 <field 2>
残りの行に文字列を挿入します。一致したら入力を終了します。メッセージそしてそれはセマフォと一致shift
。
sed
の出力は、2つの位置を持つシェルプロセスによって解釈されますshm/-sつまり、はシェルがコマンドの実行を停止し、shm の代わりに実行を開始することsed
を示します。shift
ipcrm shm <field2>
-s
純粋なシェルソリューションが必要な場合は、これが近いと思います。
set -f; IFS='
'; for l in $(ipcs);
do IFS=\ ;set -- $l
case "$1:$2:${3#bob}" in
(-*:Sh*) a=shm;;
(-*:Se*) a=-s;;
(-*:Me*) break 2;;
(*:*:) ipcrm "$a" "$2";;
esac; done
答え3
slmが示唆したようにあなたの他の質問、while
ループではなくループを使用してこれを行うことをお勧めしますfor
。
looking_at=
ipcs | while read key id owner other
do
# Keep track of which section we’re in.
if [ "$id" = "Shared" ] # $id is the second field; i.e., $2.
then
looking_at=shm
elif [ "$id" = "Semaphore" ]
then
looking_at=sem
elif [ "$id" = "Message" ]
then
break
fi
if [ "$owner" = "bob" ]
then
if [ "$looking_at" = "shm" ]
then
ipcrm shm "$id"
elif [ "$looking_at" = "sem" ]
then
ipcrm -s "$id"
fi
fi
done
これは、コマンドの出力をipcs
1 行ずつ読み取り、最初の 3 つのフィールドを key
、id
、に分割しますowner
。コメントにあるように、looking_at
変数を使用して、現在どのセクションにいるかを追跡します。次に、bob
3 番目のフィールドに が含まれるすべての行で、 を使用して、使用するオプションlooking_at
を決定しますipcrm
。