这可行,但我这样做的方式有点愚蠢。有一个更好的方法吗?
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
要使用哪个选项。