I have a process that starts every day and I'd like to create a log that says me when is completed.
I'm a newbie on Linux, I haven't programmed before, but I've tried to write this code
#!/bin/csh
set today=`date '+%Y%m%d'`
set LOG_DIR=${SL_ROOT_FOLDER}/log/cod_flow_extractor
set LOG_FILE=settlement_report_procedure
set LOG_FILE=${LOG_DIR}/${LOG_FILE}.log_$_"$today.log"
echo "$LOG_FILE"
#eval $LOG_FILE
#exec >> $LOG_FILE 2>&1
#exec $LOG_FILE
alias log
echo "currDate=`date +%Y%m%d.%H:%M:%S`"
When I executed it, I haven't got a log.
What am I doing wrong?
You should just redirect the output of the last echo statement:
#!/bin/csh
set today=`date '+%Y%m%d'`
# $SL_ROOT_FOLDER is defined elsewhere
set LOG_DIR=${SL_ROOT_FOLDER}/log/cod_flow_extractor
set LOG_FILE=settlement_report_procedure
# notice I removed excess '_$'
set LOG_FILE=${LOG_DIR}/${LOG_FILE}."$today.log"
# let's see if its a correct path
echo "$LOG_FILE"
echo "currDate=`date +%Y%m%d.%H:%M:%S`" > $LOG_FILE
Related
I have this shell :
===
#!/bin/sh -e
LogFile=/home/pi/logs/prova.log # log file
test -e $LogFile || touch $LogFile # create it if non existent
echo "(1) ======== ======== ======== Inici de PROVA.SH" >> $LogFile
echo "(2) ping 1.2.3.4" >> $LogFile
# ping 1.2.3.4 -W 3 -c 2 >> $LogFile
echo "(3) start APP" >> $LogFile
echo "LOG file is" $LogFile
exit 0
===
The output is
1) one line to screen
2) three lines to file
But if the 8th line (ping 1.2.3.4) is un-commented,
the "echo's" after the 8th line do not get written,
neither to the screen, neither to the file.
I need to understand why, and how to solve it.
I guess is something related to the fact that "ping" runs in another shell,
so the "echo's" write there.
But I don't know how to fix it.
Any pointer or URL to documentation is welcome.
Sebastian.
ping -W 3 -c 2 1.2.3.4 >> $LogFile
Put the IP/Hostname after the ping options.
Most likely:
ping fails because of wrong order of arguments: destination should be last.
Your script runs with -e so it exits at first error, so it stops after ping fails.
You don't redirect standard error for ping : the error message is lost
If you remove -e, ping still fails, but the script continues, executes the last 2 lines and you get their output (but you do not get from ping because that goes to stderr)
Solution, 2 changes:
ping -W 3 -c 2 1.2.3.4 2>&1 >> $LogFile
^^^^^^^ ^^^^
I.P as last argument & Redirect stderr to stdout before redirecting to file
so after alex answer here are my steps :
creating shell code
root#ip[/]# touch mylog.sh
root#ip[/]# nano mylog.sh
copying the code in the mylog.sh
#!/bin/bash
echo "File $1 created." >> /mylog.log
permission
root#ip[/]# chmod +x mylog.sh
creating the log file
root#ip[/]# touch mylog.log
opening icron table
incrontab -e
putting new command in
/test/ IN_CREATE mylog.sh $#$#
reloading incron - creating a new file - checking the log file
root#ip[/]# incrontab --reload
requesting table reload for user 'root'...
request done
root#ip[/]# cd test
root#ip[/test]# touch newfile.txt
root#ip[/test]# cd /
root#ip[/]# nano mylog.log
but still empty log file ... am i missing something ?
finally calling shell script with full path did the trick
so :
/test/ IN_CREATE /mylog.sh $#$#
You can usually find the incron logs in /var/log/messages
If you want to log events to a specific file you can use:
/test/ IN_CREATE mylog.sh $#$#
where mylog.sh is a shell script which handles the logging.
#!/bin/bash
echo "File $1 created." >> /home/myuser/filescreated.log
Don't forget to give execution permission to this shell script by chmod +x mylog.sh
Explanation:
As soon as you start using parameters for your command which you're calling, you have to put it all into a shell script. Since incron don't pass the arguments to your command but interprets it as an argument for itself.
Don't forget to call incrontab --reload after changing the incrontab.
Another example
incrontab -e
/text/ IN_CREATE /home/myuser/mylog.sh $# $#
mylog.sh
#!/bin/bash
echo "$(date) File $2 in $1 created." >> /home/myuser/log.txt
Following with Alexander's Baltasar answer, you could also have a script that does the redirection, and keep your end scripts free of that logic.
Below std_wrapper.sh:
#!/bin/bash
### FLAGS
set -Eeuo pipefail
### INIT SCRIPT
SCRIPT_FULLNAME=$(basename -- ${0})
usage="usage: ${SCRIPT_FULLNAME} log_file target_script target_file watched_dir event"
## ARGUMENTS
log_file="${1}"
target_script="${2}"
target_file="${3}"
watched_dir="${4}"
event="${5}"
### MAIN
if [ -z "${log_file}" ] || [ -z "${target_script}" ] || [ -z "${target_file}" ]; then
echo "${usage}" >&2
exit 1
fi
# do the actual call and apply the redirection:
${target_script} "${target_file}" "${watched_dir}" "${event}" >> "${log_file}" 2>&1
make sure the script can be run ($ chmod 770 std_wrapper.sh):
In your incrontab ($ incrontab -e):
/test/ IN_CREATE /path/std_wrapper.sh /path/log/test.create /path/actual_script.sh $# $# $%
actual_script.sh could look something like this:
#!/bin/bash
### FLAGS
set -Eeuo pipefail
### Input Parameters
filename="${1}"
watched_dir="${2}"
event="${3}"
full_filename="${watched_dir}${filename}"
### Main
dt="$(date '+%d/%m/%YT%H:%M:%S')"
echo "$dt (event:) $event (file:) $filename (dir:) $watched_dir <----- going to process ----->"
echo "sleeping 10 seconds..."
sleep 10
dt="$(date '+%d/%m/%YT%H:%M:%S')"
echo "$dt (event:) $event (full_filename:) $full_filename <----- returning from sleep -->"
Creating two files consecutively (in less than 10 seconds)
$ touch /test/new-file && sleep 5 && touch /test/another-file
Would create a log like this:
$ cat /path/log/test.create
07/11/2022T08:00:50 (event:) IN_CREATE (file:) new-file (dir:) /test/ <----- going to process ----->
sleeping 10 seconds...
07/11/2022T08:00:55 (event:) IN_CREATE (file:) another-file (dir:) /test/ <----- going to process ----->
sleeping 10 seconds...
07/11/2022T08:01:10 (event:) IN_CREATE (full_filename:) /test/new-file <----- returning from sleep -->
07/11/2022T08:01:15 (event:) IN_CREATE (full_filename:) /test/another-file <----- returning from sleep -->
Firstly,i will give the shell code:
#!/bin/bash
filename=$1
if [ -e $filename ] ; then
yesterday=`date -d yesterday +%Y%m%d`
cp $filename $filename.$yesterday
now=`date '+%Y-%m-%d%H:%M:%S'`
echo "========split log at $now========" > $filename
echo "========split log $filename to $filename.$yesterday at $now========"
else
echo "$filename not exist."
fi
The shell run successfully,and print the string ========split log at $now======== to the new created $filename.But below this string,many bytes of \0 are also written to the$filename,which is showed as follows:
My reputation score is less than 10,i can not post image,so i give the link of the picture:http://i.stack.imgur.com/QF0F2.jpg
i wrote the shell code aimed to truncate the log file created by nohup.
The original of my start command like this : nohup $cmd > $logPath 2>&1 &,
now i change it to nohup $cmd >> $logPath 2>&1 &.Someone told me that when use the mode of > the log writer program would remember the location of current log, and after truncating the log,the program will continue the location.
SOLVED! add #!/bin/bash at the top of all my scripts in order to make use of bash extensions. Otherwise it restricts itself to POSIX shell syntax. Thanks Barmar!
Also, I'll add that I had trouble with gpg decryption not working from cronjob after I got it executing, and the answer was to add the --no-tty option (no terminal output) to the gpg command.
I am fairly new to linux, so bear with me...
I am able to execute a simple script with crontab -e when logged in as ubuntu:
* * * * * /ngage/extract/bin/echoer.sh
and this bash script simply prints output to a file:
echo "Hello" >> output.txt
But when I try to execute my more complex bash script in exactly the same way, it doesn't work:
* * * * * /ngage/extract/bin/superMasterExtract.sh
This script called into other bash scripts. There are 4 scripts in total, which 3 levels of hierarchy. It goes superMasterExtract > masterExtract > (decrypt, unzip)
Here is the code for superMasterExtract.sh (top level):
shopt -s nullglob # ignore empty file
cd /str/ftp
DIRECTORY='writeable'
for d in */ ; do # for all directories in /str/ftp
if [ -d "$d$DIRECTORY" ]; then # if the directory contains a folder called 'writeable'
files=($d$DIRECTORY/*)
dirs=($d$DIRECTORY/*/)
numdirs=${#dirs[#]}
numFiles=${#files[#]}
((numFiles-=$numdirs))
if [ $numFiles -gt 0 ]; then # if the folder has at least one file in it
bash /ngage/extract/bin/masterExtract.sh /str/ftp ${d:0:${#d} - 1} # execute this masterExtract bash script with two parameters passed in
fi
fi
done
masterExtract.sh:
DATE="$(date +"%m-%d-%Y_%T")"
LOG_FILENAME="log$DATE"
LOG_FILEPATH="/ngage/extract/logs/$2/$LOG_FILENAME"
echo "Log file is $LOG_FILEPATH"
bash /ngage/extract/bin/decrypt.sh $1 $2 $DATE
java -jar /ngage/extract/bin/sftp.jar $1 $2
bash /ngage/extract/bin/unzip.sh $1 $2 $DATE
java -jar /ngage/extract/bin/sftp.jar $1 $2
echo "Log file is $LOG_FILEPATH"
decrypt.sh:
shopt -s nullglob
UPLOAD_FILEPATH="$1/$2/writeable"
DECRYPT_FOLDER="$1/decryptedFiles/$2"
HISTORY_FOLDER="$1/encryptHistory/$2"
DONE_FOLDER="$1/doneFiles/$2"
LOG_FILENAME="log$3"
LOG_FILEPATH="/ngage/extract/logs/$2/$LOG_FILENAME"
echo "DECRYPT_FOLDER=$DECRYPT_FOLDER" >> $LOG_FILEPATH
echo "HISTORY_FOLDER=$HISTORY_FOLDER" >> $LOG_FILEPATH
cd $UPLOAD_FILEPATH
for FILE in *.gpg;
do
FILENAME=${FILE%.gpg}
echo ".done FILE NAME=$UPLOAD_FILEPATH/$FILENAME.done" >> $LOG_FILEPATH
if [[ -f $FILENAME.done ]]; then
echo "DECRYPTING FILE=$UPLOAD_FILEPATH/$FILE INTO $DECRYPT_FOLDER/$FILENAME" >> $LOG_FILEPATH
cat /ngage/extract/.sftpPasswd | gpg --passphrase-fd 0 --output "$DECRYPT_FOLDER/$FILENAME" --decrypt "$FILE"
mv $FILE $HISTORY_FOLDER/$FILE
echo "MOVING FILE=$UPLOAD_FILEPATH/$FILE INTO $HISTORY_FOLDER/$FILE" >> $LOG_FILEPATH
else
echo "Done file not found!" >> $LOG_FILEPATH
fi
done
cd $DECRYPT_FOLDER
for FILE in *
do
mv $FILE $DONE_FOLDER/$FILE
echo "DECRYPTED FILE=$DONE_FOLDER/$FILE" >> $LOG_FILEPATH
done
If anyone has a clue why it refuses to execute my more complicated script, I'd love to hear it. I have also tried setting some environment variables at the beginning of crontab as well:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/local/bin:/usr/bin
MAILTO=jgardnerx85#gmail.com
HOME=/
* * * * * /ngage/extract/bin/superMasterExtract.sh
Note, I don't know that these are the appropriate variables for my installation or my script. I just pulled them off other posts and tried it to no avail. If these aren't the correct environment variables, can someone tell me how I can deduce the right ones for my particular application?
You need to begin your script with
#!/bin/bash
in order to make use of bash extensions. Otherwise it restricts itself to POSIX shell syntax.
I have a pxe server which hosts a live image of Ubuntu 12.04 and I would like to enable VNC on it.
Normally I would do this with the following command:
$ gsettings set org.gnome.Vino enabled true
However, since this live OS lives in RAM it will need to do this on bootup every time. The problem is for some reason it will not work with a script in /etc/init.d/... For the life of me I cannot figure out why gsettings doesn't work in this context..
For reference this is the script I am using in /etc/init.d:
#!/bin/bash
log=/var/log/gsettings.log
#Needed for some reason.. received info from http://stackoverflow.com/questions/10374520/gsettings-with-cron
sessionfile=`find "${HOME}/.dbus/session-bus/" -type f`
export $(grep "DBUS_SESSION_BUS_ADDRESS" "${sessionfile}" | sed '/^#/d')
set_gsettings()
{
echo "Inside set_gsettings" >> $log
#Enable vino
gsettings set org.gnome.Vino enabled true 2>&1 >> $log
gsettings set org.gnome.Vino prompt-enabled false 2>&1 >> $log
}
case "$1" in
start)
echo "Inside IT-gsettings" >> $log
set_gsettings
;;
restart|reload|force-reload)
/etc/init.d/IT-gsettings start
;;
stop)
:
;;
*)
log_success_msg "Usage: /etc/init.d/IT-gsettings {start|stop|restart|reload|force-reload}"
exit 1
;;
esac
exit 0
In short, how can I set gsettings on startup?
It is likely the script runs when still there is no session available.
Given it is a live CD and you have control of it, you might want to change the defaults values in the schema. For vino, you should change the default values in /usr/share/glib-2.0/schemas/org.gnome.Vino.gschema.xml.