Reputation: 149
I tried various steps from http://mywiki.wooledge.org/ProcessManagement and http://mywiki.wooledge.org/BashFAQ/068My but I am unable to achieve is how to kill the tail -f command after certain time interval.
my script:
#!/bin/bash
function strt ()
{
command 1..
command 2..
}
export -f strt
su user -c 'set -e && RUN_Server.sh > server.log && tail -f server.log & pid=$! { sleep 20; kill $pid; } && strt'
exit 0.
I am trying to kill the pid of tail -f server.log and proceed to 'strt' which is small function to find if jboss server is started or not.
on executing I get error as
bash: -c: line 0: syntax error near unexpected token `{' .
Upvotes: 3
Views: 3507
Reputation: 38649
I was trying something similar, namely wanted to print out the pid of a process spawned in the background with ampersand (&
), in a one-liner/single line:
$ tail -f /var/log/syslog & ; echo $!
bash: syntax error near unexpected token `;'
... but kept getting the dreaded syntax error, which brought me to this post.
What I failed to realize in my example above, is that the &
(ampersand) is also a command separator/terminator in bash
- just like the ;
(semicolon) is!! Note:
- [command] ; [command] [newline]
Semi-colons and newlines separate synchronous commands from each other.- [command] & [command]
A single ampersand terminates an asynchronous command.
So - given that the &
, which is a command line terminator in bash
, in my example above is followed by a ;
, which is also a command line terminator - bash
chokes. The answer is simply to remove the semicolon ;
, and let only the ampersand &
act as a command line separator in the one-liner:
$ tail -f /var/log/syslog & echo $!
[1] 15562
15562
$ May 1 05:39:16 mypc avahi-autoipd(eth0)[23315]: Got SIGTERM, quitting.
May 1 06:09:01 mypc CRON[2496]: (root) CMD ( [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) -delete)
May 1 06:17:01 mypc CRON[5077]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
May 1 06:25:01 mypc CRON[7587]: (root) CMD (test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ))
^C
$ May 1 06:52:01 mypc CRON[15934]: (root) CMD (test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ))
$ ps -p 15562
PID TTY TIME CMD
15562 pts/0 00:00:00 tail
$ kill 15562
$ ps -p 15562
PID TTY TIME CMD
[1]+ Terminated tail -f /var/log/syslog
$ ps -p 15562
PID TTY TIME CMD
$
... however, in this example, you have to manually kill the spawned process.
To go back to OP problem, I can reconstruct the problem with this command line:
$ tail -f /var/log/syslog & pid=$! { sleep 2; kill $pid; }
bash: syntax error near unexpected token `}'
Thinking about this - bash sees &
as separator, then sees "legal" command pid=$!
, and then - with the previous "legal" command unterminated, sees a curly brace {
which means a new command group in current shell. So the answer is simply to terminate the pid=$!
with a semicolon ;
, so the new command group can properly start:
$ tail -f /var/log/syslog & pid=$! ; { sleep 2; kill $pid; }
[1] 20228
May 1 05:39:16 mypc avahi-autoipd(eth0)[23315]: Got SIGTERM, quitting.
May 1 06:09:01 mypc CRON[2496]: (root) CMD ( [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) -delete)
May 1 06:17:01 mypc CRON[5077]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
May 1 06:25:01 mypc CRON[7587]: (root) CMD (test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ))
May 1 06:52:01 mypc CRON[15934]: (root) CMD (test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ))
$ ps -p 20228
PID TTY TIME CMD
[1]+ Terminated tail -f /var/log/syslog
$
Note that the tail -f
process seems to terminate property, but in my bash
(version 4.2.8(1)), I have to press Enter in shell, to see the "[1]+ Terminated ...
" message.
Hope this helps,
Cheers!
Upvotes: 0
Reputation: 107040
The problem you're having is that you slee
p command won't run until after you kill your tail
.
The command structure:
command1 && command2
says to run command1
and if it exits with an exit code of 0
, then run command2
. It's equivalent to this:
if command1
then
command2
fi
I had a similar situation to this a while ago. I had to start up a Weblogic server, wait until the server started, then do something on the server.
I ended up using named pipes (Directions) to do this. I ran the command that started the Weblogic server through this named pipe. I then had another process read the pipe, and when I saw the startup string, I broke out of my loop and continued my program.
The link above should give you complete directions on doing just that.
Upvotes: 0
Reputation: 241918
pid=$! { sleep 20 ; kill $pid; }
What are you trying to do? Maybe just adding a semicolon before {
can help?
Upvotes: 0