I've got an incrontab rule set up to react to a file being added to a particular directory on my ubuntu box, and run a script. This works fine, but my goal is to print the output of that script to a file.
I've tried a few different ways to go about it, and the only way I've been able to get it working so far is to take the generated command that incrontab creates, and run it myself. So my thinking is that its possible, I'm likely just missing something obvious to an experience linux user.
I've shortened some of the commands for brevity's sake. "watchdir" "scriptPath" and "arg1" are all paths. I am bringing in two arguments to the script, arg1, and the filename wildcard from the cron job.
I've tried:
(These run the script, but don't output to file)
watchdir IN_CREATE scriptPath arg1 $# >> /home/ubuntu/logs/log-$# 2>&1
watchdir IN_CREATE scriptPath arg1 $# &>> /home/ubuntu/logs/log-$#
(These do nothing at all)
watchdir IN_CREATE /bin/bash scriptPath arg1 $# >>
/home/ubuntu/log/log-$# 2>&1
watchdir IN_CREATE /bin/bash scriptPath arg1 $# &>>
/home/ubuntu/log/log-$#
If I run 'tail /var/log/syslog' and grab the command generated from the incrontab below and paste it into the shell, it works fine
watchdir IN_CREATE scriptPath arg1 $# &>> /home/ubuntu/logs/log-$#
This works
scriptPath arg1 mission-LHPUQ7ezcF0s0UwVgUR.txt &>>
/home/ubuntu/logs/log-mission-LHPUQ7ezcF0s0UwVgUR.txt
Any insight as to what I could be missing?
I had a similar problem and found out, that incron simply ignores the output redirection and hands them over to the script as arguments:
https://askubuntu.com/questions/1164166/incrond-does-not-execute-custom-script
So your solution may be to first call a wrapper script that does the output redirection to the log file.
If you watch a directory, then $# holds the directory path and $# the file that triggered the event. If you watch a file, then $# holds the complete path to the file and $# is empty. Reference.
Related
I am writing shell script to install my application. I have more number of commands in my script such as copy, unzip, move, if and so on. I want to know the error if any of the commands fails. Also I don't want to send exit codes other than zero.
Order of script installation(root-file.sh):-
./script-to-install-mongodb
./script-to-install-jdk8
./script-to-install-myapplicaiton
Sample script file:-
cp sourceDir destinationDir
unzip filename
if [ true]
// success code
if
I want to know by using variable or any message if any of my scripts command failed in root-file.sh.
I don't want to write code to check every command status. Sometimes cp or mv command may fail due to invalid directory. At the end of script execution, I want to know all commands were executed successfully or error in it?
Is there a way to do it?
Note: I am using shell script not bash
/* the status of your last command stores in special variable $?, you can define variable for $? doing export var=$? */
unzip filename
export unzipStatus=$?
./script1.sh
export script1Status=$?
if [ !["$unzipStatus" || "$script1Status"]]
then
echo "Everything successful!"
else
echo "unsuccessful"
fi
Well as you are using shell script to achieve this there's not much external tooling. So the default $? should be of help. You may want to check for retrieval value in between the script. The code will look like this:
./script_1
retval=$?
if $retval==0; then
echo "script_1 successfully executed ..."
continue
else;
echo "script_1 failed with error exit code !"
break
fi
./script_2
Lemme know if this added any value to your scenario.
Exception handling in linux shell scripting can be done as follows
command || fallback_command
If you have multiple commands then you can do
(command_one && command_two) || fallback_command
Here fallback_command can be an echo or log details in a file etc.
I don't know if you have tried putting set -x on top of your script to see detailed execution.
Want to give my 2 cents here. Run your shell like this
sh root-file.sh 2> errors.txt
grep patterns from errors.txt
grep -e "root-file.sh: line" -e "script-to-install-mongodb.sh: line" -e "script-to-install-jdk8.sh: line" -e "script-to-install-myapplicaiton.sh: line" errors.txt
Output of above grep command will display commands which had errors in it along with line no. Let say output is:-
test.sh: line 8: file3: Permission denied
You can just go and check line no.(here it is 8) which had issue. refer this go to line no. in vi.
or this can also be automated: grep specific line from your shell script. grep line with had issue here it is 8.
head -8 test1.sh |tail -1
hope it helps.
I tried multiple scenarios but these things are more of a headace. I tried writing this bash also for the same, but need to change in the same file which i need to execute. Can someone help me with the same.
#!/bin/bash -p
if [ $# -lt 1 ]; then
echo "No arguments provided"
exit 0
fi
CURRENT_DIR=`pwd`
EXEC_DIR=`dirname "$1"`
FILENAME="`basename $1`"
cd $EXEC_DIR
CMD="./$FILENAME ${#:2}"
$CMD
cd $CURRENT_DIR
i need some two liner to work with the same file which i need to execute.
If your script is present in /opt/ and you are in /opt/dir/ then you can run the script from there only like this --> ../script.sh it will run the script from previous folder and run it in present folder
The easiest way is to use the full path of the file/script you want to execute :
/path/to/file/example.bash
You will stay in your current directory, but your script example.bash will be executed.
I have a file name myFirstFile that contains certain commands.
But I am not able to excecute them.
If I want to execute this as a program, which code should be implemented?
If you want to execute your program, it should start with:
#!/bin/sh
It's the generic script file "header". It indicates that the script is a shell script (if it's bash script you should have #!/bin/bash, etc.). If you want to execute it, you should call chmod +x ./myFirstFile to give privileges to call it as program, and then you can start your script normally: ./myFirstFile.
Make this file executable* and give it *.sh extention like:
"myFirstFile.sh"
Than run it from terminal (or crontab - it can do things for you when you sleep :) ) like:
cd directory/you/have/that/file
sh ./myFirstFile.sh
*Im not shure that making it executable is the most secure thing you can do. All my sh scripts are and I never digged into this issue, so make sure its cool
Also make sure you have "#!/bin/bash" in first line - sometimes it helps (dont know why, Google it)
edit: for example my script for starting Minecraf server looks like this
start.sh
#!/bin/bash
BINDIR=$(dirname "$(readlink -fn "$0")")
cd "$BINDIR"
while true
do
java -Xmx3584M -jar craftbukkit.jar
echo -e 'If you want to completely stop the server process now, press ctrl-$
echo "Rebooting in:"
for i in {5..1}
do
echo "$i..."
sleep 1
done
echo 'Restarting now!'
done
You have to make the file executable:
chmod +x myFirstFile
Then you can execute the commands in it:
./myFirstFile
I need to execute a groovy script file from bash, and I need the script to have a working directory of the directory it exists in.
That is, in my bash script, I'm doing this:
/opt/script/myscript.groovy &
But this seems to set the working directory to /etc/init.d, the directory I'm calling from. How do I change the working directory for that script to /opt/script?
If you are using start-stop-daemon inside your /etc/init.d script, you can take advantage of the -d parameter for achieving this:
-d, --chdir path
Chdir to path before starting the process. This is done after the chroot if the -r|--chroot option is set. When not specified, start-stop-daemon will chdir to the root directory before starting the process.
/etc/init.d
probably you are runnig (starting) that script from /etc/init.d?
Add cd /opt/script at the first line of the script
OR
...to keep it dynamic, add:
cd "$(dirname "$0")"
In bash putting that in the script works best:
HERE=$(cd -- $(dirname ${BASH_SOURCE[0]}) > /dev/null && pwd)
cd -- "$HERE"
This will succeed even with the following invocation (of /path/to/script.sh):
PATH="/path/to:$PATH" bash script.sh
where HERE=$(dirname $0) would fail.
Optionally you could also use pwd -P instead of just pwd, then $HERE will contain the realpath (canonicalized absolute pathname) as of man 3 realpath.
Something like this maybe:
SCRIPT=/opt/script/myscript.groovy
pushd `dirname $SCRIPT`
./`basename $SCRIPT`
popd
I have a cron job set like
php /home/novinarb/public_html/index.php --uri="cron/24satahr"
but the 'uri' param doesn't get to the php script at all. I also tried without the -- in front of uri but still nothing. Any ideas?
A more robust method would be to accept command-line arguments in your PHP script with getopt() or $argv and making it executable. An example with $argv called script.php:
#!/usr/bin/php
<?php
if (isset($argv[1])):
echo $argv[1];
endif;
?>
Make it executable:
chmod +x script.php
And execute:
./script.php "cron/24satahr"
Will output:
cron/24satahr
I was facing the same problem but was able to fix it after reading the manual entry for php.
Initially I had something set like:
/usr/bin/php -f /path/to/php/script.php -c 1426 >> /tmp/script.php.log 2>&1
I was able to fix it by changing the line to:
/usr/bin/php -f /path/to/php/script.php -- -c 1426 >> /tmp/script.php.log 2>&1
As per the manual entry the syntax is:
php [options] [ -f ] file [[--] args...]
Also,
args... Arguments passed to script. Use '--' args when first argument starts with '-' or script is read from stdin
Going by that, my cron command becomes:
/usr/bin/php -f /path/to/php/script.php -- -c 1426 >> /tmp/script.php.log 2>&1
and it works!
Is the php script running at all?
I suspect you need to provide the full path to php in your crontab line. Even though cron jobs run as you, they don't have any of your login environment set up; this means they don't have your $PATH.