Isso funciona, mas a maneira como fiz isso é meio boba. Existe uma maneira melhor de fazer isso?
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
É assim que o ipcs fica para mim quando o executo.
$ 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
Preciso executar esses dois comandos regularmente.
ipcrm -s $(ipcs | grep bob | awk '{printf "%s ",$2}')
ipcrm shm $(ipcs | grep bob | awk '{printf "%s ",$2}')
Então eu estava pensando que poderia fazer algo assim.
if [ `$(ipcs | grep Shared | awk '{print $2}')` == "Shared"]
ipcrm shm $(ipcs | grep bob | awk '{printf "%s ",$2}')
Quero fazer esse primeiro comportamento até que $2 seja igual ao Semáforo.
if [ `$(ipcs | grep Semaphore | awk '{print $2}')` == "Semaphore"]
ipcrm -s $(ipcs | grep bob | awk '{printf "%s ",$2}'
Então, para resumir, quero que o primeiro bloco if seja executado depois de ver "Compartilhado". Então eu quero o segundo bloco if depois de ver "Semáforo".
Responder1
Se bem entendi, você deseja executar o comando ipcrm shm <ids>
para todos os segmentos de memória compartilhada do usuário bob. Em seguida, o comando ipcrm -s <ids>
para todos os Semaphore Arrays do usuário bob.
Para fazer isso, use os seguintes comandos (você não precisa fazer um loop em um script):
Para a parte de segmentos de memória compartilhada:
ipcrm shm $(ipcs -m | awk '$3=="bob" {printf "%s ",$2}')
Para a parte do Semaphore Array:
ipcrm -s $(ipcs -s | awk '$3=="bob" {printf "%s ",$2}')
Explicação:
Na ipcs
página de manual:
-m shared memory segments
-s semaphore arrays
A awk
parte imprime os ids somente quando o terceiro campo é bob.
Responder2
Talvez...
ipcs | sed -n '
s/[^ ]* *//
/^Messages/q
/^Semaphores/cshift
/ *bob .*/!d;s///
/ /!s/./ipcrm $1 &/p
'| sh -s -- shm \-s
Isso exclui linhas que não contêm a stringprumocomo o terceiro campo delimitado por espaçoouque não possuem em seu segundo campoMensagens/Semáforos.
Ele insere a string ipcrm $1 <field 2>
para as linhas que permanecem. Ele encerra a entrada ao combinarMensagense substitui umSemáforoscombinar com shift
.
sed
a saída de é interpretada por um processo shell com duas posicionaisshm/-s. Então, quando sed
diz shift
que o shell para de executar o comando ipcrm shm <field2>
e começa a executar -s
no local shms.
Eu acho que se você quisesse uma solução de shell pura, isso chega perto:
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
Responder3
Como slm sugeriu emsua outra pergunta, sugiro fazer isso com um while
loop em vez de um for
loop:
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
Isso lê a saída do ipcs
comando uma linha por vez, dividindo os três primeiros campos como key
, id
, e owner
. Como diz o comentário, usamos a looking_at
variável para controlar em qual seção estamos. Então, em cada linha contida bob
no terceiro campo, usamos looking_at
para determinar qual ipcrm
opção usar.