Those look more backticks to me `. On my system single quotes aren't slanted '. Are backticks better than double quotes?
That worked :). Can you please explain why you need spaces at the beginning and end [ ] brackets for if statements? I always forget when I don't do shellscripting for awhile.
I sometimes forget how awesome awk is :).
What do you mean by not portable? Is it not posix compatible? Is there a way to make it portable?
I don't understand what you're trying to do. On a system with no active message queues, shared memory segments, or semaphores, the output from ipcs will be something like:
iIPC status from <running system> as of Thu Oct 9 11:22:09 PDT 2014
T ID KEY MODE OWNER GROUP
Message Queues:
T ID KEY MODE OWNER GROUP
Shared Memory:
T ID KEY MODE OWNER GROUP
Semaphores:
So, the output from:
ipcs|grep Shared|awk '{print $2}'
will be:
Memory:
and the condition in your if statement will always evaluate to false.
If, in addition to showing us code that doesn't work, you would also tell us what you're trying to do, we might be better able to help.
And, no. You do not want to enclose a command substitution in backquotes unless you are trying to perform a command substitution on the results of a command substitution.
It looks like we are using two different distros of Linux. Our output is a bit different. I am using Fedora.
$ 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
I am working on a C project that spawns threads, creates shared memory, and creates semaphore arrays. It is annoying to have to keep typing or searching my bash history for:
You had several options given to you in your duplicate thread, and it's not clear whether you tried any of them. Particularly, my suggestion with the while loop and printing the options to help figure out why it's not matching when it apparently should.
Please try that, and get back to me, otherwise I'm just wild guessing.
We are not using different Linux distros. I am using a UNIX system where the output produced by the ipcs utility follows the formatting requirements specified by the standards.
If what you are trying to do is to remove message queues, shared memory segments, and semaphore sets that you own, the problem you stated in this thread seems to be useless. If you save the following script in $HOME/bin/cleanipc :
#!/bin/bash
# Usage: ipcs [-mqs] | cleanipc
#
# This script reads output from the ipcs utility from standard input and uses
# ipcrm to remove all message queues, shared memory segments, and semaphore
# sets whose owner is "bob".
echo ipcrm $(awk -v user="bob" '
$2 == "Shared" {
type = " -m "
next
}
$2 == "Message" {
type = " -q "
next
}
$2 == "Semaphore" {
type = " -s "
next
}
/^0x/ && $3 == user {
o = o type $2
}
END { print o
}')
and make it executable using:
chmod +x $HOME/bin/cleanipc
then the command:
ipcs -ms | cleanipc
it will show you an ipcrm command that will remove all shared memory segments and semaphore sets owned by "bob". If that looks like what you want to do, remove the echo shown in red in the script to have the script actually remove those IPC facilities.
Use different (or no options) on the ipcs command to process just message queues ( -q ), just shared memory segments ( -m ), just semaphore sets ( -s ), or everything (no options).
Note that the above script will NOT work on any system where the output produced by ipcs conforms to the standards. If your ipcs produced standard format output, the following code in the above awk script:
$2 == "Shared" {
type = " -m "
next
}
$2 == "Message" {
type = " -q "
next
}
$2 == "Semaphore" {
type = " -s "
next
}
/^0x/ && $3 == user {
o = o type $2
}
would be replaced by:
$1 ~ /^(m|q|s)$/ && $5 == user {
o = o " -"$1 $2
}
Does my ipcs conform to standards? How do I know if it conforms to standards? The first method worked.
Is my understanding of this correct? After Shared is matched. Then it runs what is in {}. Then the next makes it read the next line? It ignore the Message block and Semaphore block until the column 2 is matched? It then goes to ^0x block? The process starts back over on the next line?
$2 == "Shared" {
type = " -m "
next
}
Can you please explain this part? I know you are anchoring the 0 to the beginning, then you making sure column 3 matches user which has been set to bob.
/^0x/ && $3 == user {
o = o type $2
Did I do this right? I replaced everything in the single quotes ' '. It looked like you needed to keep the first part. I thought my ipcs conformed to standards but the first method worked.
#!/bin/bash
# Usage: ipcs [-mqs] | cleanipc
#
# This script reads output from the ipcs utility from standard input and uses
# ipcrm to remove all message queues, shared memory segments, and semaphore
# sets whose owner is "bob".
echo ipcrm $(awk -v user="bob" '
$1 ~ /^(m|q|s)$/ && $5 == user {
o = o " -"$1 $2
}')
Thank you for your very detailed explanation. I wouldn't have remembered to use the bin directory.
PS: If you use mmap()'d files not shared memory for these functions, you can kiss ipcrm and all that root stuff goodbye. Also no sudo needed, everyone can do shared memory in their own files, and the files are simple to dump after an abort or to monitor during a long run.
The output you showed us from the ipcs utility on your Fedora Linux distro does not conform to the standard in lots of ways. You need to keep the full script I gave you (with the exception of the echo ) to get something that will work with the ipcs utility you have.
You said that the output from your ipcs looks like:
------ 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
so:
/^0x/ && $3 == user {
o = o type $2
}
selects lines where the 1st two characters on the line are 0x and the 3rd field is bob (which I marked in red above). For each selected line it adds a string based on the section of the output from ipcs and the ID from that line to the string saved in the variable o .
If you had a conforming ipcs utility, the output for the last line in each section would have been:
m 3440645 0x00000000 666 bob 40 1
s 262146 0x000005b1 600 bob 6
instead of the output you showed us:
0x00000000 3440645 bob 666 40 1
0x000005b1 262146 bob 600 6
So, for other people reading this thread who do have a conforming ipcs , they could use:
#!/bin/bash
# Usage: ipcs [-mqs] | cleanipc
#
# This script reads output from the ipcs utility from standard input and uses
# ipcrm to remove all message queues, shared memory segments, and semaphore
# sets whose owner matches is the person who invoked this utility as determined
# by $USER from the environment.
ipcrm $(awk -v user="$USER" '
$1 ~ /^(m|q|s)$/ && $5 == user {
o = o " -"$1 $2
}
END { print o
}')