How to have bash script's log file be auto-created after removal - linux

I have a bash script file date.sh:
#!/bin/bash
while true
do
sleep 1
echo "date------ "$(date)
done
I run it
$ ./date.sh >> date.log 2>&1 &
I can see a date.log in there and be updating, but after I removed it, it won't be auto created, even I manually recreated it, the file won't update , I want date.log be auto created and update after it be removed.

In this code, date.log is opened just once:
./date.sh >> date.log 2>&1 &
If you want date.log to recreate itself if missing, you need to re-open each time that you write to it:
#!/bin/sh
while true; do
sleep 1
echo "date------ $(date)" >>date.log
done
Because the redirection >>date.log is inside the loop, the file is opened (and closed) with each loop. That is what is needed to re-create the file.
You can then run it:
./date.sh &
Now, if you delete or rename date.log, a new file called date.log will be created and written to.
Note that re-opening and re-closing the file with each loop is less efficient. Unless you want the re-create-itself feature, it is faster to open and close just once.
Example
This shows that we can delete date.log while the script is running in the background and the file will soon be recreated and appended to:
$ ./date.sh &
[1] 15678
$ cat date.log
date------ Sat Jul 30 00:51:28 PDT 2016
date------ Sat Jul 30 00:51:29 PDT 2016
date------ Sat Jul 30 00:51:30 PDT 2016
date------ Sat Jul 30 00:51:31 PDT 2016
$ rm -f date.log
$ cat date.log
date------ Sat Jul 30 00:51:38 PDT 2016
date------ Sat Jul 30 00:51:39 PDT 2016
date------ Sat Jul 30 00:51:40 PDT 2016
date------ Sat Jul 30 00:51:41 PDT 2016
What if date.sh cannot be modified
Suppose that date.sh is owned by others and we cannot modify it. In that case:
./date.sh | awk -v f=date.log '{print>>f; close(f)}' &
awk loops through each line of input and, for each line, it opens date.log, appends to it, and closes it.
Alternatively, if for some reason we wanted to stick with pure shell:
./date.sh | while IFS= read -r line; do printf "%s\n" "$line" >>date.log; done &

Related

Mutt not working inside Crontab but works out of it

After research the whole Internet can't find a solution to it.
I have a script which is working perfectly when I execute it from terminal.
#!/bin/bash
zip -r -j Tato.zip Csv
rm -r Csv/*.*
echo "blahblahblah" | mutt -s "Test" email#gmail.com -a Tato.zip
rm *.zip
but actually it does not work when I put it inside a crontab.
55 15 * * 7 /home/pi/Script.sh
wanted it to be executed on Sundays at 15.55.
And this is the output that /var/log/syslog tells me
Nov 1 15:55:01 raspberrypi sSMTP[3939]: Unable to locate mail
Nov 1 15:55:01 raspberrypi sSMTP[3939]: Cannot open mail:25
Nov 1 15:55:01 raspberrypi /USR/SBIN/CRON[3936]: (pi) MAIL (mailed 1 byte of output; but got status 0x0001, #012)
Don't know what to do anymore.
All help will be appreciated.

How to print the previous linux command's output?

The problem is:
After user enter a linux command.
How can I get the output of the first command using another command?
Note: we cannot redirect output of first command to somewhere.
Using history expansion
$ date -d "12:00"
Thu Sep 19 12:00:00 EDT 2013
$ d=$(!!)
$ echo $d
Thu Sep 19 12:00:00 EDT 2013

Copy all typed command in a linux console & their result to a file

I'm trying to make a script to automatically install programs and configure them on my Fedora 19 linux distribution.
To create it, I made a VM and I'm typing all the command manually in my "Terminal" application.
I'd like to be able to log all what I've typed and all the output (stdin & stderr & stdout if I understood it well) so I can use this log to make my script.
Is there a way to do this ?
You can use the script command to record your session:
$ script session.txt
Script started, file is session.txt
$ ls
session.txt
$ exit
Script done, file is session.txt
$ cat session.txt
Script started on Wed 31 Jul 2013 07:36:40 AM CEST
$ ls
session.txt
$ exit
Script done on Wed 31 Jul 2013 07:36:42 AM CEST

Bash: Program next execution of current script using 'at'

I want to execute a script and make it schedule the next execution. A sample would be:
#!/bin/bash
TMP=/tmp/text.txt
SCRIPT=$(readlink -f $0)
date >>$TMP
at -f $SCRIPT now + 1 minutes >>$TMP 2>&1
echo -e "\n" >>$TMP
A sample execution would do as follows:
First execution OK. Schedules to next minute
Second execution writes OK but doesn't schedule
Resulting output would be:
tue mar 5 14:34:01 CET 2013
job 15 at 2013-03-05 14:35
tue mar 5 14:35:00 CET 2013
job 16 at 2013-03-05 14:36
[now at 2013-03-05 14:38]
atq outputs nothing and I don't see any /var/at/jobs (In fact, ls /var/at* outputs nothing. There is no message in any user in /var/mail/. I'm trying on a CentOS release 5.6 x86_64
Anyone has any hint as to what may be happening?
suspectus, you have hit the point... echo $SCRIPT gives '/bin/bash'... I've manually written the full path and now it works

What is the *nix command to view a user's default login shell

What is the *nix command to view a user's default login shell?
I can change the default login shell with chsh, but I don't know how to get what is the user's default shell.
Pseudocode
$ get-shell
/usr/bin/zsh
The canonical way to query the /etc/passwd file for this information is with getent. You can parse getent output with standard tools such as cut to extract the user's login shell. For example:
$ getent passwd $LOGNAME | cut -d: -f7
/bin/bash
The command is finger.
[ken#hero ~]$ finger ken
Login: ken Name: Kenneth Berland
Directory: /home/ken Shell: /bin/tcsh
On since Fri Jun 15 16:11 (PDT) on pts/0 from 70.35.47.130
1 hour 59 minutes idle
On since Fri Jun 15 18:17 (PDT) on pts/2 from 70.35.47.130
New mail received Fri Jun 15 18:16 2012 (PDT)
Unread since Fri Jun 15 17:05 2012 (PDT)
No Plan.
The login shell is defined in /etc/passwd. So you can do:
grep username /etc/passwd
I think what you are looking for is this:
#!/bin/bash
grep "^$1" /etc/passwd | cut -d ':' -f 7
Save that as get-shell somewhere in your path (probably ~/bin) and then call it like:
get-shell userfoo
SHELL variable is used to represent user's current shell
echo $SHELL

Resources