# Bash if run a command

**URL:** <https://community.unix.com/t/bash-if-run-a-command/347026>\
**Category:** Shell Programming and Scripting\
**Created:** [October 9, 2014, 6:21am UTC](https://community.unix.com/t/bash-if-run-a-command/347026 "2014-10-09T06:21:58Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![cokedude](https://community.unix.com/letter_avatar/cokedude/32/6_22734026db12803ebb3e059622ac3534.png) [@cokedude](https://community.unix.com/u/cokedude)\
**Post date:** [October 9, 2014, 6:21am UTC](https://community.unix.com/t/bash-if-run-a-command/347026/1 "2014-10-09T06:21:58Z")

</div>

I am having trouble with bash. I am trying to put a command in an if statement and then compare it to a string.

This works perfectly.

```nohighlight
echo $(ipcs | grep Shared | awk '{print $2}')

```

When I put it in an if statement I get some problems.

```nohighlight
$ if ["$(ipcs | grep Shared | awk '{print $2}')" -eq "Shared"]; then echo expression evaluated as true; else echo expression evaluated as false; fi
bash: [: missing `]'
expression evaluated as false

$ if ["$(ipcs | grep Shared | awk '{print $2}')" = "Shared"]; then echo expression evaluated as true; else echo expression evaluated as false; fi
bash: [: missing `]'
expression evaluated as false

$ if ["$(ipcs | grep Shared | awk '{print $2}')" == "Shared"]; then echo expression evaluated as true; else echo expression evaluated as false; fi
bash: [: missing `]'
expression evaluated as false

```

I tried ==, =, and -eq because I wasn't sure which one to use.

---

<div class="post-metadata">

**Author:** ![gull04](https://community.unix.com/user_avatar/community.unix.com/gull04/32/14972_2.png) [@gull04](https://community.unix.com/u/gull04)\
**Post date:** [October 9, 2014, 6:29am UTC](https://community.unix.com/t/bash-if-run-a-command/347026/2 "2014-10-09T06:29:19Z")

</div>

Hi,

Need to enclose in single quotes like so;

```nohighlight
if [`$(ipcs | grep Shared | awk '{print $2}')` == "Shared"]

```

Regards

Dave

---

<div class="post-metadata">

**Author:** ![MadeInGermany](https://community.unix.com/letter_avatar/madeingermany/32/6_22734026db12803ebb3e059622ac3534.png) [@MadeInGermany](https://community.unix.com/u/MadeInGermany)\
**Post date:** [October 9, 2014, 6:32am UTC](https://community.unix.com/t/bash-if-run-a-command/347026/3 "2014-10-09T06:32:14Z")

</div>

You need a space after the `[` and before the closing `]`

```nohighlight
if ["$(ipcs | grep Shared | awk '{print $2}')" = "Shared"]; then 

```

Shorter is

```nohighlight
if ["$(ipcs | awk '/Shared/ {print $2}')" = "Shared"]; then 

```

Both are not portable.

---

<div class="post-metadata">

**Author:** ![cokedude](https://community.unix.com/letter_avatar/cokedude/32/6_22734026db12803ebb3e059622ac3534.png) [@cokedude](https://community.unix.com/u/cokedude)\
**Post date:** [October 9, 2014, 7:26am UTC](https://community.unix.com/t/bash-if-run-a-command/347026/4 "2014-10-09T07:26:57Z")

</div>

> [@gull04](#):
>
> Hi,
> 
> Need to enclose in single quotes like so;
> 
> ```plaintext
> if [`$(ipcs | grep Shared | awk '{print $2}')` == "Shared"]
> 
> ```
> 
> Regards
> 
> Dave

Those look more backticks to me `. On my system single quotes aren't slanted '. Are backticks better than double quotes?

> [@madeingermany](#):
>
> You need a space after the `[` and before the closing `]`
> 
> ```plaintext
> if ["$(ipcs | grep Shared | awk '{print $2}')" = "Shared"]; then 
> 
> ```
> 
> Shorter is
> 
> ```plaintext
> if ["$(ipcs | awk '/Shared/ {print $2}')" = "Shared"]; then 
> 
> ```
> 
> Both are not portable.

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?

---

<div class="post-metadata">

**Author:** ![Don\_Cragun](https://community.unix.com/user_avatar/community.unix.com/don_cragun/32/2682_2.png) [@Don\_Cragun](https://community.unix.com/u/Don_Cragun)\
**Post date:** [October 9, 2014, 2:29pm UTC](https://community.unix.com/t/bash-if-run-a-command/347026/5 "2014-10-09T14:29:40Z")

</div>

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:

```nohighlight
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:

```nohighlight
ipcs|grep Shared|awk '{print $2}'

```

will be:

```nohighlight
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.

---

<div class="post-metadata">

**Author:** ![cokedude](https://community.unix.com/letter_avatar/cokedude/32/6_22734026db12803ebb3e059622ac3534.png) [@cokedude](https://community.unix.com/u/cokedude)\
**Post date:** [October 10, 2014, 3:46am UTC](https://community.unix.com/t/bash-if-run-a-command/347026/6 "2014-10-10T03:46:58Z")

</div>

> [@don cragun](#):
>
> 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:
> 
> ```plaintext
> 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:
> 
> ```plaintext
> ipcs|grep Shared|awk '{print $2}'
> 
> ```
> 
> will be:
> 
> ```plaintext
> 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.

```plaintext
$ 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:

```plaintext
ipcrm -s $(ipcs | grep bob | awk '{printf "%s ",$2}')
ipcrm shm $(ipcs | grep bob | awk '{printf "%s ",$2}')

```

So I was thinking I could do something like this.

```plaintext
if [`$(ipcs | grep Shared | awk '{print $2}')` == "Shared"]
ipcrm shm $(ipcs | grep bob | awk '{printf "%s ",$2}')

```

I wanna do that first behavior until $2 equals Semaphore.

```plaintext
if [`$(ipcs | grep Semaphore | awk '{print $2}')` == "Semaphore"]
ipcrm -s $(ipcs | grep bob | awk '{printf "%s ",$2}'

```

)

I am not sure how to this. I have been reading the bash documentation for several days with no luck.

---

<div class="post-metadata">

**Author:** ![Corona688](https://community.unix.com/letter_avatar/corona688/32/6_22734026db12803ebb3e059622ac3534.png) [@Corona688](https://community.unix.com/u/Corona688)\
**Post date:** [October 10, 2014, 11:23am UTC](https://community.unix.com/t/bash-if-run-a-command/347026/7 "2014-10-10T11:23:48Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Don\_Cragun](https://community.unix.com/user_avatar/community.unix.com/don_cragun/32/2682_2.png) [@Don\_Cragun](https://community.unix.com/u/Don_Cragun)\
**Post date:** [October 10, 2014, 1:09pm UTC](https://community.unix.com/t/bash-if-run-a-command/347026/8 "2014-10-10T13:09:38Z")

</div>

> [@cokedude](#):
>
> It looks like we are using two different distros of Linux. Our output is a bit different. I am using Fedora.
> 
> ```plaintext
> $ 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:
> 
> ```plaintext
> ipcrm -s $(ipcs | grep bob | awk '{printf "%s ",$2}')
> ipcrm shm $(ipcs | grep bob | awk '{printf "%s ",$2}')
> 
> ```
> 
> So I was thinking I could do something like this.
> 
> ```plaintext
> if [`$(ipcs | grep Shared | awk '{print $2}')` == "Shared"]
> ipcrm shm $(ipcs | grep bob | awk '{printf "%s ",$2}')
> 
> ```
> 
> I wanna do that first behavior until $2 equals Semaphore.
> 
> ```plaintext
> if [`$(ipcs | grep Semaphore | awk '{print $2}')` == "Semaphore"]
> ipcrm -s $(ipcs | grep bob | awk '{printf "%s ",$2}'
> 
> ```
> 
> )
> 
> I am not sure how to this. I have been reading the bash documentation for several days with no luck.

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` :

```plaintext
#!/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:

```plaintext
chmod +x $HOME/bin/cleanipc

```

then the command:

```plaintext
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:

```plaintext
$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:

```plaintext
$1 ~ /^(m|q|s)$/ && $5 == user {
        o = o " -"$1 $2
}

```

---

<div class="post-metadata">

**Author:** ![cokedude](https://community.unix.com/letter_avatar/cokedude/32/6_22734026db12803ebb3e059622ac3534.png) [@cokedude](https://community.unix.com/u/cokedude)\
**Post date:** [October 10, 2014, 3:15pm UTC](https://community.unix.com/t/bash-if-run-a-command/347026/9 "2014-10-10T15:15:15Z")

</div>

> [@don cragun](#):
>
> 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` :
> 
> ```plaintext
> #!/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:
> 
> ```plaintext
> chmod +x $HOME/bin/cleanipc
> 
> ```
> 
> then the command:
> 
> ```plaintext
> 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:
> 
> ```plaintext
> $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:
> 
> ```plaintext
> $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?

```plaintext
$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.

```plaintext
/^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.

```plaintext
#!/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.

---

<div class="post-metadata">

**Author:** ![DGPickett](https://community.unix.com/letter_avatar/dgpickett/32/6_22734026db12803ebb3e059622ac3534.png) [@DGPickett](https://community.unix.com/u/DGPickett)\
**Post date:** [October 10, 2014, 4:05pm UTC](https://community.unix.com/t/bash-if-run-a-command/347026/10 "2014-10-10T16:05:19Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Don\_Cragun](https://community.unix.com/user_avatar/community.unix.com/don_cragun/32/2682_2.png) [@Don\_Cragun](https://community.unix.com/u/Don_Cragun)\
**Post date:** [October 10, 2014, 4:25pm UTC](https://community.unix.com/t/bash-if-run-a-command/347026/11 "2014-10-10T16:25:42Z")

</div>

No. Yes. Sure. And, no!

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:

```nohighlight
------ 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:

```nohighlight
/^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:

```nohighlight
m 3440645 0x00000000 666 bob 40 1                       
s 262146 0x000005b1 600 bob 6         

```

instead of the output you showed us:

```nohighlight
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:

```nohighlight
#!/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
}')

```
