이것은 효과가 있지만 내가 하는 방식은 약간 어리석습니다. 더 좋은 방법이 있나요?
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가 세마포어와 같아질 때까지 첫 번째 작업을 수행하고 싶습니다.
if [ `$(ipcs | grep Semaphore | awk '{print $2}')` == "Semaphore"]
ipcrm -s $(ipcs | grep bob | awk '{printf "%s ",$2}'
요약하자면, "shared"를 본 후 첫 번째 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
의 출력은 두 위치의 쉘 프로세스에 의해 해석됩니다.매끈한/-s. 따라서 sed
쉘 shift
이 명령 실행을 중지 ipcrm shm <field2>
하고 -s
shms 위치에서 실행을 시작합니다.
순수한 쉘 솔루션을 원한다면 다음과 같습니다.
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