how to schedule .sh script on linux server? - linux

I'm new to linux, and I have linux server with script ftp.sh which transfers files to windows server.
I have tried to schedule it at 06:15 every day via crontab command in PUTTY/winSCP
15 06 * * * sh ftp.sh
and get this error message:
command not found
I have also tried to schedule it from a Windows batch file with
start folderName\putty.exe -ssh root#10.*.*.* 22 -pw "password"
It succeeds with the login, but can't execute navigation to /opt/dan/scripts or execute the sh ftp.sh command in it.
What am I doing wrong? Is there another way I havn't thought about?

sh cannot execute ftp.sh since ftp.sh is propably not in the PATH environment variable. If you write the full path to ftp.sh you may succeed.
15 06 * * * sh /the/path/to/ftp.sh
Or depending on your setup
15 06 * * * /path/to/sh /the/path/to/ftp.sh
Or
15 06 * * * /the/path/to/ftp.sh

Your OS doesn't seem to recognise 'sh' as a command, as stated here:
command not found
This usually means it's not installed on the particular flavour of Linux you're using. You should use a different file interpreter, or if you're sure that 'sh' is installed then you should use the absolute path to that program in the cron command.
If you type the following in to a terminal session, it should bring up the full path:
whereis sh
Or alternatively:
which sh

Read more about the PATH variable. It is not the same in interactive shells (they usually set it in your ~/.bashrc) and in cron jobs.
So specify an absolute path for your ftp.sh shell script in your crontab and start that script with a shebang like #!/bin/sh
BTW, consider switching to Linux entirely (e.g. by installing some Linux distribution on your laptop)

Related

Linux Cronjob not running powershell script, but the script is able to run in terminal

I have a PowerShell Script that updates a database table. I would like to set this up in the Cronjob to run daily. However it doesnt seem to work in the cronjob. At the moment I have setting it forward a couple minutes so that I dont have to wait.
CronTab:
* * * * * pswh -File "/home/administrator/PowerShellScripts/Update-Set-Table.ps1"
Terminal:
pswh -File "/home/administrator/PowerShellScripts/Update-Set-Table.ps1"
Working perfectly when I run that command in the terminal but it doesnt seem to be running from the cronjob.
you need to specify the full path to the executable pwsh. you can do so by using which APPNAME in a terminal.
which pwsh
then change the line in your crontab accordingly. for me the working result looks like this:
* * * * * /snap/bin/pswh -File "/home/administrator/PowerShellScripts/Update-Set-Table.ps1"
Cron's lack of environment has this side effect: the working directory changes. In my case I was writing to a file I expected to be in the script's directory which was being created & written to nicely in $HOME.
The script's directory is held in the PoSh variable $PSScriptRoot
PoSh has a symlink at /usr/bin/pwsh so the full path is not necessary (for me anyway)
The current (Vixie) cron allows standard variables which can be used for paths. Check the author in man crontab
If you're script has a #!/usr/bin/pwsh shebang & is executable it executes like any script without specifying 'pwsh'
BTW if you're displaying to screen, say a dialog, the cron job must be prefaced with env DISPLAY=:0(or some other number) in order to display. eg env DISPLAY=:0 pwsh $ScriptHome/DiskFull-WereGoingToCrash.ps1 -display

cronjob does not execute a script that works fine standalone

I have my php script file in /var/www/html/dbsync/index.php. When cd /var/www/html/dbsync/ and run php index.php it works perfectly.
I want to call PHP file through sh file, the location of SH file is as below
/var/www/html/dbsync/dbsync.sh
This is the content of the dbsync.sh file is:
/usr/bin/php /var/www/html/dbsync/index.php >> /var/www/html/dbsync/myscript.log 2>&1 -q -f
When I cd /var/www/html/dbsync/ and run ./dbsync.sh it works perfectly as well.
Now if I set up crontab as below:
1 * * * * /var/www/html/dbsync/dbsync.sh /var/www/html/dbsync
However, this crontab is not working as expected.
What can be wrong?
As seen in comments, the problem is that you are not defining what program should be used to execute the script. Take into account that a cronjob is executed in a tiny environment; there, not much can be assumed. This is why we define full paths, etc.
So you need to say something like:
1 * * * * /bin/sh /var/www/html/dbsync/dbsync.sh /var/www/html/dbsync
# ^^^^^^^
/bin/sh being the binary you want to use to execute the script.
Otherwise, you can set execution permissions to the script and add a shell-script header telling it what interpreter to use:
#!/bin/sh
If you do this, adding the path of the binary is not necessary.
From Troubleshooting common issues with cron jobs:
Using relative paths. If your cron job is executing a script of some
kind, you must be sure to use only absolute paths inside that script.
For example, if your script is located at /path/to/script.phpand
you're trying to open a file called file.php in the same directory,
you cannot use a relative path such as fopen(file.php). The file must
be called from its absolute path, like this: fopen(/path/to/file.php).
This is because cron jobs do not necessarily run from the directory in
which the script is located, so all paths must be called specifically.
Also, I understand you want to run this every minute. If so, 1 * * * * won't do. Intead, it will run at every 1st minute past every hour. So if you want to run it every minute, say * * * * *.
It is important to understand "login shell" and "interactive shell" what they means.
login shell: is briefly when you sign in with ssh session and get a terminal window where you can enter shell commands. After login the system executes some files(.bashrc) and sets some environment variables such as the PATH variable for you.
interactive shell :After login on a system, you can startup manually shell terminal(s). The system executes some profile file assigned to your account (.bash_profile, .bash_login,.profile). This files also sets some environment variables and initialize PATH variable for your manually opened shell session.
By OS started shell scripts and cron jobs does not fit in above mentioned way for starting a shell. Therefore no any system scripts(.bashrc) or user profiles are executed. This means our PATH variable is not initialized. Shell commands could not found because PATH variable does not point to right places.
This explains why your script runs successfully if you start it manually but fails when you start it via crontab.
Solution-1:
Use absolute path of every shell command instead of only the command name used in your script file(s).
instead of "awk" use "/usr/bin/awk"
instead of "sed" use "/bin/sed"
Solution-2: Initialize environment variables and especially the PATH variable before executing shell scripts!
method 1, add this header in your dbsync.sh:
#!/bin/bash -l
method 2, add bash -l in your cron file:
1 * * * * bash -l /var/www/html/dbsync/dbsync.sh /var/www/html/dbsync

Ubuntu cron shebang not working

I have a script with this as the shebang #!/usr/bin/env node.
When cron runs my script, I get this error /usr/bin/env: node: No such file or directory.
When i run the script as my user the script runs fine, just not as cron. I'm guessing it's because node is not on the PATH of the user that runs cron?
How can I get this shebang to work with cron?
$ which node gives me
/home/myuser/.nvm/v0.11.14/bin/node
Cron jobs run in a restricted environment. In an interactive shell, your $PATH is probably set in your $HOME/.bash_profile or $HOME/.bashrc. Cron jobs are executed in an environment that hasn't sourced those files, so your user-specific $PATH settings will not be available.
You can see what that environment looks like by temporarily creating a crontab entry like:
* * * * * printenv > crontab-environment
You can explicitly set $PATH in your crontab, either in the command itself:
* * * * * PATH=$PATH:/home/myuser/.nvm/v0.11.14/bin some_command
or in a separate line in your crontab:
PATH = /usr/bin:/bin:/home/myuser/.nvm/v0.11.14/bin
You can't (directly) use the usual PATH=$PATH:/new/dir syntax to append a directory to your $PATH in an environment setting line, because variable references are not replaced in such a line. They are processed in crontab command lines.
man 5 crontab for details.
Another option is to use an explicit full path in the script itself, changing
#!/usr/bin/env node
to
#!/home/myuser/.nvm/v0.11.14/bin/node
You'll need to customize this for each system where node is installed in a different place. Or you can arrange for node (or nodejs?) to be installed in a consistent place.

Crontab absolute path not working

I have a script to backup my database at /home/<user>/bin/dbbackup. The script is executable by all users, and owned by me. The files /etc/cron.allow and /etc/cron.deny do not exist.
In my crontab I have the following lines (including a new blank line after the last line of code):
#reboot /home/<user>/.dropbox-dist/dropboxd
30 2 * * * bash /home/<user>/bin/dbbackup
However, cron is not running my dbbackup script. When I run a manual test of the script it works. When I run this test on the command line: * * * * * /bin/echo "cron works" >> ~/file I get the following error:
No command 'dbbackup' found, did you mean:
Command 'dvbackup' from package 'dvbackup' (universe)
Command 'tdbbackup' from package 'tdb-tools' (main)
dbbackup: command not found
My server is running Ubuntu Trusty. Any help please?
As the comments noted, it appears that amiga_os needed remove the reference to bash in the line.
30 2 * * * bash /home/<user>/bin/dbbackup
Should be.
30 2 * * * /home/<user>/bin/dbbackup
I usually just call scripts from their path and use "#!/bin/bash" (or wherever your bash lives) as the first line of the script. It appears the amiga_os had already done this, which is good. I don't like putting sentences into cron because it makes me nervous.
I think it was a path issue as cron executes as the user but does not read the bash profile and therefore does not work exactly like it would under your shell as it might not have access to your $PATH.

how to use crontab to run a Graphical program such as "gedit"

how to use crontab to run a Graphical program such as "gedit"
57 12 * * * gedit --display=localhost:0
Can not successfully open the program and display it.
--display=localhost:0 can be causing error ,
Following code will also do the trick
57 12 * * * export DISPLAY=:0 && /usr/bin/gedit
There is a reason why i added entire path of gedit ,
Utilities in /bin and /usr/bin can be opened using cron just by specifying its name so
/usr/bin/gedit or just gedit will work.
May a time command you use to start certain utility on terminal doesn't work using cron ,this is because cron passes a minimal set of environment variables to your jobs.May be required env PATH variable is not available with Cron hence it is not able to locate that utility.
you can find a detailed explanation in first reply here.

Resources