Das funktioniert, aber die Art, wie ich es gemacht habe, ist irgendwie albern. Gibt es eine bessere Möglichkeit, das zu tun?
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
So sieht ipcs für mich aus, wenn ich es ausführe.
$ 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
Ich muss diese beiden Befehle regelmäßig ausführen.
ipcrm -s $(ipcs | grep bob | awk '{printf "%s ",$2}')
ipcrm shm $(ipcs | grep bob | awk '{printf "%s ",$2}')
Also dachte ich, ich könnte so etwas machen.
if [ `$(ipcs | grep Shared | awk '{print $2}')` == "Shared"]
ipcrm shm $(ipcs | grep bob | awk '{printf "%s ",$2}')
Ich möchte dieses erste Verhalten ausführen, bis 2 $ gleich Semaphore sind.
if [ `$(ipcs | grep Semaphore | awk '{print $2}')` == "Semaphore"]
ipcrm -s $(ipcs | grep bob | awk '{printf "%s ",$2}'
Zusammenfassend möchte ich, dass der erste if-Block ausgeführt wird, nachdem ich „Shared“ sehe. Dann möchte ich den zweiten if-Block ausführen, nachdem ich „Semaphore“ sehe.
Antwort1
Wenn ich das richtig verstehe, möchten Sie den Befehl ipcrm shm <ids>
für alle Shared Memory Segments des Benutzers Bob ausführen. Dann den Befehl ipcrm -s <ids>
für alle Semaphore Arrays des Benutzers Bob.
Verwenden Sie dazu die folgenden Befehle (Sie müssen kein Skript in einer Schleife ausführen):
Für den Teil „Gemeinsam genutzte Speichersegmente“:
ipcrm shm $(ipcs -m | awk '$3=="bob" {printf "%s ",$2}')
Für den Semaphore-Array-Teil:
ipcrm -s $(ipcs -s | awk '$3=="bob" {printf "%s ",$2}')
Erläuterung:
Aus der ipcs
Manpage:
-m shared memory segments
-s semaphore arrays
Das awk
Teil druckt die IDs nur, wenn das 3. Feld Bob ist.
Antwort2
Vielleicht...
ipcs | sed -n '
s/[^ ]* *//
/^Messages/q
/^Semaphores/cshift
/ *bob .*/!d;s///
/ /!s/./ipcrm $1 &/p
'| sh -s -- shm \-s
Dadurch werden Zeilen gelöscht, die die Zeichenfolge nicht enthaltenBobals drittes durch Leerzeichen getrenntes Feldoderdie in ihrem zweiten Feld nicht habenNachrichten/Semaphoren.
Es fügt den String ipcrm $1 <field 2>
für die verbleibenden Zeilen ein. Es beendet die Eingabe, wennMitteilungenund es ersetzt einSemaphorenÜbereinstimmung mit shift
.
sed
Die Ausgabe wird von einem Shell-Prozess mit zwei Positionsalarmen interpretiert.shm/-s. Wenn dies also der sed
Fall ist shift
, stoppt die Shell die Ausführung des Befehls ipcrm shm <field2>
und startet die Ausführung -s
an der Stelle von shms.
Ich denke, wenn Sie eine reine Shell-Lösung wollten, kommt diese hier dem nahe:
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
Antwort3
Wie slm vorgeschlagen hat aufdeine andere Frage, ich schlage vor, dies mit einer while
Schleife statt einer for
Schleife zu tun:
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
Dadurch wird die Ausgabe des ipcs
Befehls zeilenweise gelesen, wobei die ersten drei Felder als key
, id
, und aufgeteilt werden owner
. Wie im Kommentar angegeben, verwenden wir die looking_at
Variable, um zu verfolgen, in welchem Abschnitt wir uns befinden. Anschließend bob
verwenden wir in jeder Zeile, die im dritten Feld enthält, looking_at
um zu bestimmen, welche ipcrm
Option verwendet werden soll.