這可行,但我這樣做的方式有點愚蠢。有一個更好的方法嗎?
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
我需要定期運行這兩個命令。
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 區塊。然後我想要在看到「信號量」後的第二個 if 區塊。
答案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
僅當第三個欄位為 bob 時,該awk
部件才會列印 id。
答案2
或許...
ipcs | sed -n '
s/[^ ]* *//
/^Messages/q
/^Semaphores/cshift
/ *bob .*/!d;s///
/ /!s/./ipcrm $1 &/p
'| sh -s -- shm \-s
刪除不包含該字串的行鮑伯作為第三個空格分隔字段或者他們的第二個領域沒有訊息/信號量。
ipcrm $1 <field 2>
它為剩餘的行插入字串。匹配時退出輸入留言它取代了信號量與 匹配shift
。
sed
的輸出由具有兩個位置的 shell 進程解釋勻稱/-s。因此,當sed
表示shift
shell 停止運行命令ipcrm shm <field2>
並開始-s
在 shms 位置運行時。
我想如果你想要一個純 shell 解決方案,這很接近:
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
這次 讀取一行指令的輸出,將前三個欄位分解為key
、id
和owner
。正如註釋所說,我們使用變數來looking_at
追蹤我們所在的部分。bob
looking_at
ipcrm