# how to create a pid?



## wonslung (Jul 29, 2009)

I'm really new to shell scripting...painfully new...i've managed to do some simple stuff but i'm having a slight problem with this one....


I have a cronjob that starts a program at reboot and i want to make another cronjob to check to see if that one is running and restart it if it's not.  I need this to work on multiple user too.

This program doesn't create a pid when it is started so i'm thinking i should write a script to start it and create a pid.  I need it to do this based on user name so it doesn't get confused....or to put the pid in the users home directory or SOMETHING.....I'm stuck and can't find a lot of resources for my problem....any help would be appreciated.


----------



## graudeejs (Jul 29, 2009)

```
#!/bis/sh
Exec some_app
echo $!
exit 0
```

This will start some_app and echo it's pid

Every app has pid.... you just need to get it
Another option is to use pgrep

check this:
http://code.google.com/p/playd/source/browse/sh/playd.sh#107
It shows example how to use pids


----------



## DutchDaemon (Jul 29, 2009)

You can also use '$$' from within a script.


```
#!/bin/sh
                            
echo $$
```

That shows the pid of the script that you just ran. You can redirect it to a file if you wish, and put other stuff in it, like $USER, $HOME, etc.


----------



## wonslung (Jul 29, 2009)

ok...this is really weird...i've figured out how to use ps and grep to check if something is running and it SEEMS to be working....but it's not
here's what i used

```
if ps -f | grep -v grep | grep "$SERVICE" > /dev/null
then 
   echo "$SERVICE service running, everything is fine"
else
    echo "$SERVICE is not running"
fi
```

it doesn't work but i was thinking it should....when i type 
ps -f|grep -v grep |grep SOMEPROGRAM

ok...it's not behaving the same way in the script as if i was to just type it....i removed the /dev/null to see what was happening and it seems grep is picking up the script itself.....


then is shows the program, if i use soemthing that isn't running it just returns empty....what am i doing wrong?


----------



## DutchDaemon (Jul 30, 2009)

Use pgrep.


----------



## wonslung (Jul 30, 2009)

DutchDaemon said:
			
		

> Use pgrep.



yah, but i need it to work for multple users.....
i read the man file but i'm still not 100% sure how to make this work...i want this script to work for 2 users at the same time who use it in thier crontab.  I'm going to use it to check if a program is running and start it if it isnt.  right now if i use pgrep it doesn't show only processes running for the user i type it on...i'm sure i'm just too new and i'm missing something important, i'll keep reading up on it i guess.

I thought i was on the right track before because when i'd type the command in shell it worked fine....but for some reason in the script it doesn't

edit: i think the pgrep will work if i can figure out a way to make the script check which user is running it and do somethingh like this

pgrep -u user programname


----------



## rbelk (Jul 30, 2009)

Wonslung, here is what I use for starting or restarting processes with one controlling user, i.e user1.


```
#!/bin/sh
ps auwx | grep -w program_name | grep -v grep > /dev/null
if [ $? != 0 ]; then
    /usr/local/bin/program_name
fi
```

Here is the code for a process that can be controlled by multiple users.


```
Step 1. Install the port "security/sudo"
Step 2. As root type in visudo and add the following to the file
        %staff  localhost = NOPASSWD: /bin/ps
        NOTE: "staff" is a default group in /etc/group, it can be any group or one you create.
        NOTE: This will allow users in the staff group to type in "sudo ps auwx" with out a password to see all system processes.
Step 3. Add users to the staff group that can start/restart /usr/local/bin/program_name
        pw usermod user1 -G staff
        pw usermod user2 -G staff

Now the above script will work correctly if you change the line
        ps auwx | grep -w program_name | grep -v grep > /dev/null
to look like this
        sudo ps auwx | grep -w program_name | grep -v grep > /dev/null
```

I have typed this from memory, I will check tomorrow morning at work to see if I typed in something wrong.


----------



## wonslung (Jul 30, 2009)

i ended up using pgrep

```
if pgrep -u $USER $SERVICE
then
    echo "$SERVICE service running, everything is fine"
else
    echo "$SERVICE is not running"
fi
```
works perfectly

thanks for all the help...i need to find a good book on shell scripting


----------



## graudeejs (Jul 30, 2009)

I learned sh from this:
http://www.grymoire.com/Unix/Sh.html


----------



## rbelk (Jul 30, 2009)

FYI, my script programming has changed tremendously in the last  few years. I try to write all my shell scripts with only Bourne Shell syntax, /bin/sh on most all UNIX systems. But some of the linux systems are now moving to Dash for /bin/sh. I also only use very common utilities, and try not to use system specific ones like I have in the past, I.E. pgrep and pkill for example.

The reason for this is that I admin at least 12-to-14 different UNIX variants at work, AIX, Solaris, SCO(bad,bad), HPUX, IRIX, and most all of the variants of Linux and BSD. I can't count the total number of systems in my head, it's too many and we have 3 UNIX Admins.

If you keep your toolset to a minimum all of your scripts can be reused instead of rewritten! That's a big administrative plus!!
I only install OpenSSH, SUDO, and the GNUtils on the the boxes and thats it. A small overhead but the smaller the better.


----------



## wonslung (Jul 30, 2009)

rbelk said:
			
		

> FYI, my script programming has changed tremendously in the last  few years. I try to write all my shell scripts with only Bourne Shell syntax, /bin/sh on most all UNIX systems. But some of the linux systems are now moving to Dash for /bin/sh. I also only use very common utilities, and try not to use system specific ones like I have in the past, I.E. pgrep and pkill for example.
> 
> The reason for this is that I admin at least 12-to-14 different UNIX variants at work, AIX, Solaris, SCO(bad,bad), HPUX, IRIX, and most all of the variants of Linux and BSD. I can't count the total number of systems in my head, it's too many and we have 3 UNIX Admins.
> 
> ...



that makes a lot of sense....but the script worked in both linux and freebsd....i'm really new to this...if i can write ANYTHING that works i'm happy.

I am looking for some good ideas/resources though....so pgrep isn't a good idea because it changes from system to system? is that what you mean?


----------



## rbelk (Jul 30, 2009)

wonslung said:
			
		

> that makes a lot of sense....but the script worked in both linux and freebsd....i'm really new to this...if i can write ANYTHING that works i'm happy.
> 
> I am looking for some good ideas/resources though....so pgrep isn't a good idea because it changes from system to system? is that what you mean?



Yes, that's what I mean. A good comparison of system differences can by found at Rosetta Stone for Unix. It even gets worse trying to remember the PS syntax differences from Linux and BSD, and be careful with PKILL it does work differently on most systems.

It's easier for me because I admin different systems. If your only going to be admin'ing only BSD go ahead and do anything you want.


----------



## SirDice (Jul 30, 2009)

rbelk said:
			
		

> It even gets worse trying to remember the PS syntax differences from Linux and BSD, and be careful with PKILL it does work differently on most systems.


Pkill and pgrep work exactly the same on bsd, linux and solaris. It's killall you need to be careful with. Killall on Solaris really kills all processes.


----------



## wonslung (Jul 30, 2009)

rbelk said:
			
		

> It's easier for me because I admin different systems. If your only going to be admin'ing only BSD go ahead and do anything you want.



no, i'm using opensolaris, freebsd and linux on about 5 or 6 machiens atm


----------



## rbelk (Jul 30, 2009)

SirDice said:
			
		

> Pkill and pgrep work exactly the same on bsd, linux and solaris. It's killall you need to be careful with. Killall on Solaris really kills all processes.



Sorry SirDice, I meant to say killall and not pkill. To late at night and half-asleep I guess.


----------



## SirDice (Jul 30, 2009)

rbelk said:
			
		

> Sorry SirDice, I meant to say killall and not pkill. To late at night and half-asleep I guess.



No worries, I have the same thing when I try to post answers before my morning coffee


----------



## wonslung (Jul 30, 2009)

lol, all of you know more than me...i was so thrilled when i got the first script working and then this one..its a major feeling of accomplishment.

I gotten really comfortable in unix, this seems like the next logical step.


----------



## SirDice (Jul 30, 2009)

Having thought about this a bit, you can probably get away with a really simple cron entry.

Cronning something like *pgrep myprogram || /usr/local/bin/myprogram* might just be enough.

Pgrep returns 0 when 1 or more processes are found, if that's the case the other part of the logic OR is executed. When pgrep returns 1 (when no processes are found) execution stops (the other part of the OR is not executed).


----------



## DutchDaemon (Jul 30, 2009)

It's the other way around (a.k.a. *!&&*) 

1 --> ||
0 --> exit


----------



## SirDice (Jul 30, 2009)

DutchDaemon said:
			
		

> It's the other way around (a.k.a. *!&&*)
> 
> 1 --> ||
> 0 --> exit



Err.. Am I making a logic error? I though not..

a || b

if a returns 0, b will be executed. If a returns 1, execution stops.

a && b

If a returns 0, execution stops. If a returns 1, b will be executed.

Crap, you're right... 

It should be

```
pgrep mprogram && /usr/local/bin/myprogram
```


----------



## DutchDaemon (Jul 30, 2009)

No,


```
pgrep myprogram || /usr/local/bin/myprogram
```

was entirely correct 

You just bungled up the reasoning behind it 


```
a && b --> if a = true, do b
a || b --> if a = false, do b
```

More coffee!


----------



## SirDice (Jul 30, 2009)

DutchDaemon said:
			
		

> No,
> 
> 
> ```
> ...



More coffee indeed... 0 is false and 1 is true, right?

Pgrep returns 0 (false) if it finds processes. It returns 1 (true) when it doesn't. 
Hence it should be && because you want to start the process when pgrep can't find any.

Frigging confusing :i


----------



## DutchDaemon (Jul 30, 2009)

No, 0 = true, 1 = false ... for *exit codes*, at least. With sysctl and such it's the other way around!


```
$ pgrep sendmail
910
906
$ echo $?
0

$ pgrep sendmail || echo "Sendmail OFF"
910
906
$ pgrep sendmail && echo "Sendmail ON"
910
906
Sendmail ON
```


----------



## SirDice (Jul 30, 2009)

DutchDaemon said:
			
		

> No, 0 = true, 1 = false ... for *exit codes*, at least. With sysctl and such it's the other way around!



Yeah, you're right. /bin/true returns exit code 0 aka "no error, it works".

Regular boolean algebra makes 0 false aka "off".

So my first option (||) was indeed correct :e


----------



## DutchDaemon (Jul 30, 2009)

Yes, and for the record (and the confused):

true(1)
false(1)


----------



## wonslung (Jul 31, 2009)

SirDice said:
			
		

> Having thought about this a bit, you can probably get away with a really simple cron entry.
> 
> Cronning something like *pgrep myprogram || /usr/local/bin/myprogram* might just be enough.
> 
> Pgrep returns 0 when 1 or more processes are found, if that's the case the other part of the logic OR is executed. When pgrep returns 1 (when no processes are found) execution stops (the other part of the OR is not executed).



that is similar to what i did, hold on, i'll show you what i did

```
#!/bin/sh
SERICE=

if pgrep -u $USER $SERVICE > /dev/null
then
    echo "$SERVICE service running, everything is fine"
else
    echo "$SERVICE is not running"
fi
```

i add the service name i want to check for, and add a command under the else and it works perfectly.   It checks if it is running for each user because of pgrep -u $USER
i'm really new to this sort of stuff but if people push me in the right direction i can do it =)


----------

