Setting cron for boto-rsync - cron

I am trying to run boto-rsync
using script.sh:
#!/bin/bash
echo `date`
echo "start"
boto-rsync -d 2 -a <access key> -s <secure key> s3://db-dump/hourly/2013/ /mnt/dir
echo "stop"
It works perfectly fine.
But when I run this using crontab, it ignores boto-rsync line.
Can anybody help?

Nine times out of ten, when you have a problem where something runs fine until you put it into a cron script, the underlying issue is that the cron script is running as a different user (root, usually) and the environment is not set up to access the command in question. So try doing a "su" and then typing "boto-rsync" and see if it's able to find the command.

I got the solution for this.
We need to add python and location of file
#!/bin/bash
echo `date`
echo "start"
python <location of boto-rsync> -d 2 -a <access key> -s <secure key> s3://db- dump/hourly/2013/ /mnt/dir
echo "stop"

Related

Can't write to file with script

I have written a script that is supposed to run some commands, reboot my ubuntu server and then after the server boots up, resume operation, and removes the entry from the bash file.
I have been trying for hours to figure out why my script won't write to .bashrc (or any file for that matter). Testing the commands individually works just fine. However, when run through my script nothing is written to the file. At this point I am stumped and would really like a fresh pair of eyes to help as I am sure the reason is silly and probably something I am missing. This would be my first script so sorry if this ends up being a stupid question. I put the "sudo reboot command in a comment so I won't have to reboot each time.
The script's name is test.sh and is run from ~/ . I hope this is clear and I didn't miss anything.
#!/bin/bash
echo "Script initiating"
#condition for script to run after reboot, created later on
if [ ! -f /var/run/bootflag ]; then
echo "First run"
script="bash ~/test.sh"
#this will add the script in the bash file so it will be ran on next boot
echo "$script" >> ~/.bashrc
echo "bash entry added"
#creating flag file to check if this is a second run
sudo touch /var/run/bootflag
echo "Flag created"
echo "Rebooting..."
#sudo reboot
else
echo "resuming script..."
echo "cleaning up..."
#remove the bash entry by replacing it with a space
sed -i '/bash/d' ~/.bashrc
echo "bash entry removed"
#remove the boot flag
sudo rm -f /var/run/bootflag
echo "bootflag removed"
echo "running commands post-reboot"
#commands here
echo "script exiting"
fi
I finally figured it out.
Because I was running the script with sudo, the script would take the relative path ~/.bashrc for the root user. The script was working fine all along, I was just looking at my user's .bashrc and was expecting things to appear, when all along the root user's .bashrc file was being written in.
I used sudo inside the script for all elevated commands and run the script normally without sudo and there it is, working as expected.
As I thought, this was beyond silly after all. At least I learned something today.
Thank you all for taking the time to reply and help, I really appreciate it.

Can't get remote ssh stdout output in cron, but in my terminal it works

I run into an issue last week that drives me crazy. I wrote a BASH script which does a remote ssh connection to acamai and than performs a simple 'ls'. I want to redirect the 'ls' sdtout output to a given file.
While the script itself works like a charm when run manually, it does not while it runs via cron. The cronjob runs as root and each command works as expected expect the ssh command. My System is Gentoo Linux and cron is the old but gold vixie-cron.
To reduce the 200 LOC I put the basics herein which alone (as a single script) are enough to demonstrate the problem.
#!/bin/bash
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin'
#set -x
shopt -s lastpipe
exec 2>log.out
(ssh -i <path to key> -o HostKeyAlgorithms=+ssh-dss -o StrictHostKeyChecking=no <account#example.com> 'ls -r <path>') > '/root/listing.txt'
Even in -vvv debug mode of ssh I can see, that everything works...just except that I get no stdout output.
Than I tried something else that I found in another posting on the internet:
#!/bin/bash
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin'
#set -x
shopt -s lastpipe
exec 2>log.out
(ssh -T -i <path to key> -o HostKeyAlgorithms=+ssh-dss -o StrictHostKeyChecking=no <account#example.com> 'ls -r <path>' </dev/zero) > '/root/listing.txt'
Drawback here, I start a ssh session that I can't close and I guess its due to /dev/zero.
Another approach was to TEE Pipe the sub-shell of the ssh command...this worked for a short time ( and why not yet anymore ?!)
Now I'm clueless and need help. Cron has its PATH, uses BASH etc. Curious my boss did that with success with java (and he hates BASH...).
Any explanation and helpful tips are greatly welcome.
I have same issue, I make script for CRON and it gets output from remote SSH host.
If i run script manually - it works as should. But when CRON runs it - i get just a part of remote output.
I cant realise why its happening.
#!/bin/sh
pass=123
filelist=$(sshpass -p "$pass" ssh -q -tt -o StrictHostKeyChecking=no user#"10.10.10.10" "list")
filestring=$(echo "$filelist" | grep -Po "(\S+\s\S+\s+\d+\s\d{2}:\d{2}:\d{2}\s\d{4})\slist0\.lst")
filedate=${filestring% list0.lst}
echo $filedate
filestamp=$(date -d "$filedate" +"%s")
echo $filestamp
When i get echos in file via CRON - there are date from 0:00:00 - field with date (echo $filedate) is empty. But when i run manually - i get normal date with time...
It really bother me.
Help?
I found solution - add "-tt" to ssh command and all input goes to variable.
filelist=$(sshpass -p "$pass" ssh -q -tt -o StrictHostKeyChecking=no user#"10.10.10.10" "list")

Script produces different result when executed by Bash than by cron

Please consider following crontab (root):
SHELL=/bin/bash
...
...
0 */3 * * * /var/maintenance/raid.sh
And the bash script /var/maintenance/raid.sh:
#!/bin/bash
echo -n "Checking /dev/md0... "
if ! [ $(mdadm --detail /dev/md0 | grep -c "active sync") -eq 2 ]; then
mdadm --detail /dev/md0 | mail -s "Raid problem /dev/md0" "my#email.com";
echo "ERROR"
else
echo "ALL OK"
fi;
#-------------------------------------------------------
echo -n "Checking /dev/md1... "
...
And this is what happen when...
...executed from shell prompt (bash):
Mail with mdadm --detail /dev/md0 output is sent to my email (proper behaviour)
...executed by cron:
Blank mail is sent to my email (subject is there, but there is no message)
Why such difference and how to fix it?
As indicated in the comments, do use full paths on crontab scripts, because crontab does have different environment variables than the normal user (root in this case).
In your case, instead of mdadm, /sbin/mdadm makes it.
How to get the full path of a command? Using the command command -v:
$ command -v rm
/bin/rm
cron tasks run in a shell that is started without your login scripts being run, which set up paths, environment variables etc.
When building cron tasks, prefer things like absolute paths and explicit options etc
Before running your script as a cron job, you can test it with no environment variables using env -i
env -i /var/maintenance/raid.sh

Run a shell script in new terminal from current terminal

How do you run a shell script in a new terminal in Linux from a terminal like "start test.bat" in Windows, also it should be working in the console mode.
Here's a simple example to get you started:
To write a shell script, do this on your command prompt:
echo -e '#!/bin/sh\n echo "hello world"' > abc.sh
This writes:
#!/bin/sh
echo "hello world"
To a file called abc.sh
Next, you want to set it to executable by:
chmod +x abc.sh
Now, you can run it by:
./abc.sh
And you should see:
hello world
On your terminal.
To run it in a new terminal, you can do:
gnome-terminal -x ./abc.sh
or, if it's xterm:
xterm -e ./abc.sh
Here's a list of different terminal emulators.
Alternatively, you just run it in your current terminal, but background it instead by:
./abc.sh &
I came here wanting to figure out how to make a script spawn a terminal and run it self in it, so for those who want to do that I figured out this solution:
if [ ! -t 0 ]; then # script is executed outside the terminal?
# execute the script inside a terminal window with same arguments
x-terminal-emulator -e "$0" "$#"
# and abort running the rest of it
exit 0
fi
For gnome try this.
Replace ls with the command you want to run
gnome-terminal -x sh -c "ls|less"
I hope this is what you want
As of January 2020, the -e and -x option in gnome-terminal still run properly but throw out the following warnings:
For -e:
# Option “-e” is deprecated and might be removed in a later version
of gnome-terminal.
# Use “-- ” to terminate the options and put the command line to
execute after it.
For -x:
# Option “-x” is deprecated and might be removed in a later version
of gnome-terminal.
# Use “-- ” to terminate the options and put the command line to
execute after it.
Based on that information above, I confirmed that you can run the following two commands without receiving any warning messages:
gnome-terminal -- /bin/sh -c '<your command>'
gnome-terminal -- ./<your script>.sh
I hope this helps anyone else presently having this issue :)

How to run screen executing a command over ssh with tty

I tried many things today to have ssh start a screen session which executes a command. The goal is to run a command on a remote machine and to be able to see the output and to detach and reattach latter. I want to do it from within a script without any interaction except detaching the screen session to close. No satisfying solution so far.
ssh -t ${host} "\
source ~/.bashrc; \
echo \"done.\"; \
cd \"$exedir\"; \
if [ \$? -ne 0 ]; then \
echo \"could not cd into directory\"; \
exit 1; \
fi; \
echo \"executing remotexe.sh ...\"; \
screen -S "remotexe" -t "remotexe" -R "nice -n$prio ./remotexe.sh ${exeparams[#]}";"
Some of the problems I encounter are related to the strange ways to pass commands to screen/ssh/bash which interfere with arguments and options (I don't quite understand why they do not use -- to interpret whatever follows as commands with arguments). The above version almost works. The remaining difficulty is that commands in remotexe.sh (in particular make) obviously miss exports and definitions from .bashrc. This is why I tried to include the source ~/.bashrc. I tried to add similar commands or explicit exports to remotexe.sh but it behaves as if it was executed by /bin/sh. If I do a conventional ssh login I can immediately run the remotexe.sh script without error. I also tried adding shell -$SHELL to my .screenrc.
Where is the mistake in this solution? How can I correct it?
I haven't tested your code at all, and will not vouch for the sanity of this, but you definitely have a quoting error. Try:
ssh -t ${host} "
source ~/.bashrc;
echo done.;
cd \"$exedir\" || exit 1;
echo executing remotexe.sh ...;
screen -S remotexe -t remotexe -R nice -n$prio ./remotexe.sh ${exeparams[#]};"

Resources