# Problem to run a bash script like a daemon at boot



## sonysun (Dec 20, 2009)

Hello,

I've installed Syslog-ng 3, Postgresql 8 and php-syslog-ng

I use a script in order to pipe the output into postgresql.

When I run this script by hand like :

`./usr/local/bin/syslog_postgres.sh &`
It's OK


The script is  :


```
#!/bin/bash

if [ -e /tmp/pgsql.pipe ]; then
        while [ -e /tmp/pgsql.pipe ]
                do
                        psql -q -U mydbusername syslog < /tmp/pgsql.pipe
        done
else
        mkfifo /tmp/pgsql.pipe
fi
```

I've read many post :

A solution I've read it's to put my script in /usr/local/etc/rc.d

The result look's like the script was executed only on time.
(not like a daemon)
So it doesnt work for me.

An other solution I've tested is to writing an other script like this :


```
#!/bin/sh
echo "Starting syslog_postgres"
./usr/local/bin/syslog_postgres.sh &
```

Put it in /usr/local/etc/rc.d

And reboot but not working

I'm making an other try by using /etc/crontab


```
@reboot  root usr/local/bin/syslog_postgres.sh
```

But it doesn't work

Mine last test is to write an rc script looking like this


```
#!/bin/sh
#
# PROVIDE: syslog_postgres

. /etc/rc.subr

name="syslog_postgres"
rcvar=`set_rcvar`
command="/usr/local/bin/syslog_postgres"

load_rc_config $name

#
# DO NOT CHANGE THESE DEFAULT VALUES HERE
# SET THEM IN THE /etc/rc.conf FILE
#
syslog_postgres_enable=${syslog_postgres_enable-"NO"}
syslog_postgres_pidfile=${syslog_postgres_pidfile-"/var/run/utility.pid"}

pidfile="${syslog_postgres_pidfile}"

run_rc_command "$1"
```
And to add this syslog_postgres_enable="YES" on /etc/rc.conf

This kind of script don't work for me, with many different test by reading the handbook

What's is the good direction in order to run this script on reboot in the same way like doing this command :

`./usr/local/bin/syslog_postgres.sh &`

Thank you


----------



## achix (Dec 20, 2009)

From RC(8)



> If the script has a .sh suffix then it is sourced directly into the
> current shell.  Stop processing when the script that is the value of
> the $early_late_divider has been run.



So, the script in your /usr/local/etc/rc.d better have a .sh suffix. (and have the executable bit on, of course).
Anyways, you say that your script was executed one time and not as a daemon...
Maybe you mean foreground? Cause your script will always be your script no matter how you run it.

Also, your script does not work as a daemon at all when /tmp/pgsql.pipe does not exist. It just creates the pipe and exits. Is that ok with you?

Anyways,you could follow the idea of ssh-guard which smth like the one below in syslog.conf:

```
auth.info;authpriv.info     |exec /usr/local/sbin/sshguard
```

You could have your program output to PostgreSQL like above, but then again, remember that the input to psql must be valid SQL commands (which i guess syslog-ng must somehow handle) .


----------



## SirDice (Dec 20, 2009)

sonysun said:
			
		

> ```
> #!/bin/bash
> ```


Wrong path. If bash is installed (which isn't by default) it will be /usr/local/bin/bash.

But don't use bash for things like this, learn to use /bin/sh.


----------



## DutchDaemon (Dec 20, 2009)

sonysun, read this before making another post:
Posting and Editing in the FreeBSD Forums


----------



## gordon@ (Dec 20, 2009)

Not only would you have problems because you should be using /bin/sh instead of /bin/bash but you would likely have the problem where psql is probably not in the default path for system utilities (cron, and the starting shells have their PATHs severely sanitized).


----------



## SirDice (Dec 21, 2009)

The rc scripts don't run in the background. They're a run-once type of thing. If you want to start something in the background the command itself needs to be run with &, not the script.


----------



## sonysun (Dec 23, 2009)

The problem is not the path, because I took an example to write the post

In my real case I use this 
Sorry;

Thanks to SirDICE fot the explication about rc scripts;

So Now I would like to have answers in this general way :

How to run script in background like daemon at the boot, smplely what is the way or method ?

How to run a command whith the "&" at the boot

Thanks


----------



## sonysun (Dec 23, 2009)

An other things I'd like to edit my posts in order to correct faults..., is it possible ?


----------



## achix (Dec 23, 2009)

sonysun said:
			
		

> How to run a command whith the "&" at the boot



just wrap it inside the rc.d script, e.g. have a script /usr/local/etc/rc.d/syslog_postgres_wrapper.sh look like:

```
#!/bin/sh
/usr/local/bin/syslog_postgres.sh &
```
also don't forget to do:
`# chmod +x /usr/local/etc/rc.d/syslog_postgres_wrapper.sh`

Then you may try many times to see if you solved your problem by switching between single and multi user like:
`# init 1` to go to single user and then <ctrl-D> to start the multiuser mode and have your script tested. No need to reboot.


----------



## DutchDaemon (Dec 23, 2009)

Call me old-fashioned, but if I need to have a script running in the background upon boot, I just put it in /etc/rc.local.

Something like:
[cmd=]/usr/wbin/vpncheck > /var/log/vpncheck 2>&1 &[/cmd]
in /etc/rc.local works just fine for me.


----------



## sonysun (Dec 24, 2009)

Thanks for the answers, I will try after the hollidays, and give my feedback before closing this post


----------



## sonysun (Dec 25, 2009)

*not yet ok*

The principle of the two last answers works because I have placed an echo on my scripts and I read them at boot.

But, when I use this command `# ps -ax` to check the process, I don't find it.

The script I want to run is :


```
#!/bin/sh

echo "Starting syslog-ng pipe for Postgresql"

if [ -e /var/run/syslog-ng.pgsql.pipe ]; then
  while [ -e /var/run/syslog-ng.pgsql.pipe ] 
  do
    psql -U pgadmin -d logs < /var/run/syslog-ng.pgsql.pipe
  done
else
  mkfifo /var/run/syslog-ng.pgsql.pipe
fi
```

What do you think of this ?


----------



## DutchDaemon (Dec 25, 2009)

If the script is still running, it should show up in [cmd=]ps ax[/cmd] as name-of-shell name-of-script, e.g. /bin/sh /home/user/script.sh.


----------



## sonysun (Dec 26, 2009)

Yes exactly, when I run it manualy it's what I see.

But with the method /etc/rc.local, I see the echo reply at boot, but the [CMD="ps"]ax[/CMD] dont reveal the process is running.

So do you think the fact we have a loop on the script can be a problem ?

```
...
[B]while[/B] [ -e /var/run/syslog-ng.pgsql.pipe ] 
  do
    psql -U pgadmin -d logs < /var/run/syslog-ng.pgsql.pipe
  done
else
  mkfifo /var/run/syslog-ng.pgsql.pipe
...
```


May I have to run this part on background ?


```
#!bin/sh
psql -U pgadmin -d logs < /var/run/syslog-ng.pgsql.pipe &
```


----------



## DutchDaemon (Dec 26, 2009)

When you push the script into the background, you don't have to background things inside the script.

What happens when you run the script from the command-line preceded by [cmd=]sh -x[/cmd]? To me it looks like this script may actually just exit if the 'else' condition happens, or it may turn into a rather frantic  endless loop in the while loop.


----------



## sonysun (Dec 27, 2009)

*sh -x*

When I run this cmd : [CMD="sh -x "]/usr/local/sbin/syslog-ng-pgsql-pipe.sh &[/CMD]

I got this :


```
[1] 12830
+ [-e /var/run/syslog_ng.pgsql.pipe ]
+ [-e /var/run/syslog_ng.pgsql.pipe ]
+ psql -U pgadmin -d logs
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1
INSERT 0 1
...
```

Indeed when the file syslog_ng.pgsql.pipe exists, the script stays in the loop in order to insert the content of syslog_ng.pgsql.pipe into postgresql, that's the goal.

So, how can we do this kind of things ?


----------



## DutchDaemon (Dec 27, 2009)

I see no reason why the script wouldn't stay running when started from /etc/rc.local, as posted earlier. I have several scripts starting in the background using while loops, and they all stay there until they need to exit.

E.g.


```
#!/bin/sh

while true
do
if ( ping -c 3 192.168.2.1 > /dev/null 2>&1 )
then
/etc/rc.d/syslogd restart > /dev/null 2>&1
/usr/local/etc/rc.d/sshd2 forcestart > /dev/null 2>&1
echo "VPN Up" | /usr/bin/mail -s "VPN Up" root
exit 0
else 
sleep 1
fi
done
```

That one stays in the process list until the ping succeeds. Then it performs the necessary actions and exits. If the ping never succeeds, the script will keep running. Started in the background from /etc/rc.local.

Your `sh -x` run above prints a PID. Run it once again, and grep the PID from a [CMD=]ps ax[/CMD] in another screen. That should show you how the script shows up in a process list.


----------



## sonysun (Dec 29, 2009)

I ve made many tests around rc.local.

And now it looks like I've a problem with [CMD=""]psql[/CMD].

Because, at boot I obtain this :
[CMD=""]psql command not found[/CMD]

So I suppose the process is starting before postgresql.

My new questions are :

- How to sort the start of the process (betwin rc.local and the others).

- Is it possible to sort process with rc.local

- Which other solutions can help me ?


----------



## SirDice (Dec 29, 2009)

sonysun said:
			
		

> I ve made many tests around rc.local.
> 
> And now it looks like I've a problem with [CMD=""]psql[/CMD].
> 
> ...


Irrelevant. Even if the postgresql database isn't running at all it would still find the psql command. Most likely you entered a wrong path.


----------



## vivek (Dec 29, 2009)

Use full path or set PATH in script.


----------



## sonysun (Dec 30, 2009)

*It's working*

Finaly, 
It's working with this :

```
#!/bin/sh
echo "Starting syslog-postgresql pipe."
mkfifo /var/run/syslog-ng.pgsql.pipe
 while [ -e /var/run/syslog-ng.pgsql.pipe ] 
  do
    /usr/local/bin/psql -U pgadmin -d logs < /var/run/syslog-ng.pgsql.pipe
  done
```

I suppose I had 2 problems, the path and the script

Not working with


```
#!/bin/sh
echo "Starting syslog-postgresql pipe."
if [ -e /var/run/syslog-ng.pgsql.pipe ]
then
 while [ -e /var/run/syslog-ng.pgsql.pipe ] 
  do
    /usr/local/bin/psql -U pgadmin -d logs < /var/run/syslog-ng.pgsql.pipe
  done
 else
  mkfifo /var/run/syslog-ng.pgsql.pipe
fi
```

So full path is mandatory.
And the structure looks to be a problem


```
if [ -e /var/run/syslog-ng.pgsql.pipe ]
...
```

I Thank everybody


----------

