이것은 효과가 있지만 내가 한 방식은 다소 어리석습니다. 이를 수행하는 더 좋은 방법이 있습니까?
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 블록이 실행되기를 원합니다. 그런 다음 "Semaphore"를 본 후 두 번째 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
이 awk
부분은 세 번째 필드가 bob인 경우에만 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
의 출력은 두 개의 위치가 있는 쉘 프로세스에 의해 해석됩니다.shm/-s. 따라서 쉘이 명령 실행을 중지 하고 shms 위치에서 실행을 시작한다고 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
한 번에 한 줄씩 읽고 처음 세 필드를 , 및 로 key
구분 id
합니다 owner
. 설명에서 알 수 있듯이 looking_at
변수를 사용하여 현재 어느 섹션에 있는지 추적합니다. 그런 다음 bob
세 번째 필드에 포함된 모든 줄에서 사용할 옵션을 looking_at
결정하는 데 사용합니다.ipcrm