Reputation: 2270
I've only been writing actual .sh
scripts since sometime this morning, and I'm a bit stuck. I'm trying to write a script to check to see if a process is running, and to start it if it isn't. (I plan to run this script once every 10 to 15 minutes with cron
.)
Here's what I have so far:
#!/bin/bash
APPCHK=$(ps aux | grep -c "/usr/bin/rsync -rvz -e ssh /home/e-smith/files/ibays/drive-i/files/Warehouse\ Pics/organized_pics [email protected]:~/webapps/pavlick_container/public/images
")
RUNSYNC=$(rsync -rvz -e ssh /home/e-smith/files/ibays/drive-i/files/Warehouse\ Pics/organized_pics [email protected]:~/webapps/pavlick_container/public/images)
if [ $APPCHK < '2' ];
then
$RUNSYNC
fi
exit
Here's the error that I'm getting:
$ ./image_sync.sh
rsync: mkdir "/home/i/webapps/pavlick_container/public/images" failed: No such file or directory (2)
rsync error: error in file IO (code 11) at main.c(595) [Receiver=3.0.7]
rsync: connection unexpectedly closed (9 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(601) [sender=3.0.7]
./image_sync.sh: line 8: 2: No such file or directory
TRTWF is that
rsync -rvz -e ssh /home/e-smith/files/ibays/drive-i/files/Warehouse\ Pics/organized_pics [email protected]:~/webapps/pavlick_container/public/images
runs just fine from a terminal window.
What am I doing wrong?
Upvotes: 3
Views: 1988
Reputation: 107879
grep
call is wrong on two counts. The pattern shouldn't include a newline. To look for an exact string, use grep -F 'substring'
or grep -xF 'exact whole line'
.ps | grep
is highly brittle. On most unices (at least Solaris, Linux and *BSD), use pgrep: pgrep -f 'PATTERN'
returns true if there's a running process whose command line matches PATTERN
.
$(…)
means run the command inside the parentheses and capture its output. So rsync
is executed as soon as the shell hits the definition of the RUNSYNC
variable. To store a block of shell code, use a function (example below, although you don't actually need a function here, you could just write the code directly).[ $APPCHK < 2 ]
should be [ $APPCHK -lt 2 ]
: <
means input redirection. (In bash, you can also write [[ foo < bar ]]
, but that's string comparison, not numeric comparison.)~/
at the beginning of the remote rsync path is optional. Also, -e ssh
is the default unless your version of rsync is really old.exit
at the end of the script is useless, the script will exit anyway.Here's a script taking the above into account:
#!/bin/bash
run_rsync () {
rsync -rvz '/home/e-smith/files/ibays/drive-i/files/Warehouse Pics/organized_pics' \
[email protected]:webapps/pavlick_container/public/images
}
process_pattern='/usr/bin/rsync -rvz /home/e-smith/files/ibays/drive-i/files/Warehouse Pics/organized_pics imgserv@192\.168\.0\.140:webapps/pavlick_container/public/images'
if pgrep -xF "$process_pattern"; then
run_rsync
fi
Upvotes: 5
Reputation: 31471
You have a number of problems. First you are running the commands instead of putting the commands in variables. There is also a much easier way.
RUNSYNC="rsync -rvz -e ssh /home/e-smith/files/ibays/drive-i/files/Warehouse\ Pics/organized_pics [email protected]:~/webapps/pavlick_container/public/images"
if ! pgrep -f "rsync.*organized_pics"; then $RUNSYNC; fi
Upvotes: 1
Reputation: 37318
If your real code is missing a closing dlb-quote on the grep target, you're going to get weird results from the get-go.
Also, ps aux
will not list a complete command line result like you show (at least on all the the ps
s I have used).
You need to make it ps auxwww
. Often you will see people add | grep -v grep |
(you'll see why at some point). This can be reduced to changing your static search target slightly like "/usr/bin/rsync" to "/usr/bin/[r]sync ".
Other users are also helping with their comments. Using a flag file as @DiegoSevilla mentions is marginally deprecated. use a mkdir /tmp/MyWatcher_flagDir
for your flag. Directory creation is an atomic activity (where as file creations are not), and this will eliminate any errors you might encounter from having 2 copies of you monitor try to make a flag file at the same time. Only one process will succeed in making or removing a flag dir.
I hope this helps.
Upvotes: 0
Reputation: 29021
First of all, the way of checking if the program is running is mostly wrong. This may or may not work. You should rely on some special file you create when your script starts, that it is deleted when your script ends. This will tell you if the script is running, just checking if this file exists.
Then, try to either put a \
before the ~
or to remove the ~/
completely. If cron is run as other user, the tilde will be substituted in the client for the user directory. It works for the command line because maybe the home directory of your user in both machines match, but not in the user the cron is running. A guess at this point, but again, try to remove the ~/
and see if it works.
Upvotes: 0
Reputation: 1787
Looks like with your rsync command that some directory along this path is wrong: ~/webapps/pavlick_container/public/images
Have you checked on the server 192.168.0.140 in imgserv's home directory to see if "pavlick_container/public" exists? That's my guess.
Upvotes: 1