Check if file exist with current date - bash

I have an backup tool that runs every day on 2 am,
The backup output saved under existed folder named "collector"
i'm trying to write script bash,
That will check if folder named "repository" exist under the "collector" directory with the current/today date. (i.e in compare to the RHEL date)
in case folder exist with older date, send email using echo.
Appreciate the help.

Find the number of seconds for 0:00h of today (start of the date) wrt a reference time (1970-01-01 00:00:00 UTC), say today.
Then find the number of seconds the the last modified time of the desired file wrt the same reference time, say mdate.
The two values can be compared to find whether the file has created today or not.
today="$(date -d "$(date "+%D")" +%s)" # seconds at the start of the sate
mdate="$(stat -c %Y src.sh)" # seconds to the last modification
if [[ $mdate -ge $today ]]; then
echo "modified today"
else
echo "modified before today"
fi

Related

Want to get the matching Date & time from values in a file which match with the server current Date and time using shell scripts

I am a beginner in scripting and I am trying to set TPS value for a system according to the time of the server when it executes the script. I am having csv file which contains start time , End time and TPS columns which starts from 00:00 to 23:59 as follows.
StartTime,EndTime,TPS
.....,.....,...
.....,.....,...
11:30,12:00,100
12:00,12:45,200
12:45,13:30,520
.....,.....,...
.....,.....,...
23:40,23:50,920
23:50,23:59,250
Time gaps are not uniform.
if the server current time is 11:35, I want to chose the "11:30,12:00,100" line and get it into a seperate file (since 11:35 lies between 11:30-12:00). Also the chosen line will be deleted from the initial csv file.
#Current time into a variable
TS=$(date | cut -d ' ' -f4 | cut -d ':' -f1,2)
echo "Current time = $TS"
Writing the relevant line to a seperate file and removing that line from the initial file is fine for me.
if the TS=11:35, I want to get the output as "11:30,12:00,100" from that csv file.
Struggling to code how to get that matching line.
Partial answer:
Your "datalist" seem improperly conceived for full coverage. You have gaps of 1 minute at each interval which is not being captured.
To get proper coverage of all activity, you need to have first time period ending with ${EndTime_1} ... and ... the next time period starting with ${StrtTime_2}=${EndTime_1}.
When scanning, you should specify range as
if [ "${StrtTime_x}" -le "${LineTime}" -a "${LineTime}" -lt "${EndTime_x}" ]
then
...{action}...
fi
Note: the first comparison is -le , but the second is only -lt , thereby ensuring lines never match both conditions.

Unix shell scripting: date format syntax

I m trying to get yesterday date, it's not working in hp ux server.
Prev_date=$(date +"y%m%d" -d "1 day ago")
For this I m still getting current date only.
20210811
Could you please help on the same.
You missed a percentage in front of the 'y': this is working fine for me:
echo $(date +"%y%m%d" -d "1 day ago")
You can use below command, if you want.
date --date=' 1 days ago' '+%Y-%m-%d'
It will give result like
2021-09-06
I prefer this format since most of the time my scripts include SQL queries for data fetch and hence date is required to filter out data on daily basis.

shell job to compress & delete logs, once in a month

I am trying to run a schedule job on centOS to .gz and delete a whole month of logs from a directory. The logs are named somelogfile_12Apr19_18_19_41.log, somelogfile_28Mar19_07_08_20.log
I can run the below script to manually do this task
tar -cvzf somezipfile_Mar19.tar.gz somelogfile_**Mar** --remove-files
The scheduled job should run every 5th day of the month to compress and delete the previous months logs. What will the automated script be like? I am stuck at how to include only the previous months logs based on the month name (Jan,Feb,Mar, etc.)
The first problem to solve is the fact that you want a more generic function that can be run any month and produce the correct result. A good tool to get the information you need(Abbreviated month and last two digits of the year) is date.
date -d "last month" +%b
When run on April 1st, 2019 will produce "Mar".
date -d "last month" +%b%y
When run on April 1st, 2019 will produce "Mar19".
Now that we know how to get the information we want, placing the date commands in the tar command will automatically produce what the result you're looking for.
tar -cvzf somezipfile_$(date -d "last month"%b%y).tar.gz somelogfile_**$(date -d "last month" +%b)** --remove-files
The last issue that exists is scheduling, which can be solved using cron. The below statement will run /bin/foobar, on the 5th day of every month when added to your crontab file. (crontab -e to edit your crontab file)
0 0 5 * * /bin/foobar
Combining everything together, you get:
0 0 5 * * /bin/tar -cvzf somezipfile_$(date -d "last month"\%b\%y).tar.gz somelogfile_**$(date -d "last month" +\%b)** --remove-files
Don't forget to escape the %'s in the crontab

Multi-variable string not being returned via SFTP get command

I'm working on a ksh script to retrieve a file every hour via sftp that will be put on a job scheduler to be run hourly. The script must navigate to a folder with yesterday's date (remote/path/yyyymmdd/). The filename also has yesterday's date and a timestamp (filename_yyyymmdd_hhmmss.dat). Since the job will be scheduled, my script has to include the previous hour - ex. if the job runs at 11:02, the file to retrieve would be filename_yyyymmdd_10mmss.dat. The minutes and seconds will always be the same - ex 4949. There will be multiple files in the remote directory and I only want to retrieve the latest one so that there are not multiple input files being processed by our jobs. The remote directory will also have other files being created regularly, so I can't retrieve just the last modified files.
I have variables to return yesterday's date and the previous hour, but the sftp command isn't returning the full filename and isn't retrieving the file. I've tried concatenating the variables, using brackets & quotes & parenthesis, assigning multiple variables to a single variable, and exporting the variables.
vdate=$(TZ=bb24 date '+%Y%m%d')
vhour=$(date '+%H')
prevhour=$((vhour - 1))
sftp user#host << EOF
lcd /my/dir/
cd /remote/path/$vdate/
get filename_$vdate_$prevhour*.dat
bye
EOF
exit
When running the script, the file cannot be found and the full filename isn't
returned:
File "/remote/path/20190411/filename_20190411" not found.
instead of
File "/remote/path/20190411/filename_20190411_10*.dat" not found.
Every combination of variables that I try returns the same not found - ending after filename_$vdate.
I've tried some other combinations but always get the same not found:
newvar=${vdate}_${prevhour}
get filename_$newvar*.dat
and
newvar=${vdate}\\_${prevhour}
get filename_$newvar*.dat
File "/remote/path/20190411/filename_20190411" not found.
You have a problem in your script at prevhour=$((vhour - 1))
this way a text 02 after you make subtraction, it will be 1 and not 01 and it will match to undesired files, or even none as 00 - 1 is -1
[edvin]$ vdate=$(TZ=bb24 date '+%Y%m%d')
[edvin]$ vhour=$(date '+%H')
[edvin]$ prevhour=$((vhour - 1))
[edvin]$ echo $vhour
03
[edvin]$ echo $prevhour
2
[edvin]$ prevhour=$(date -d '1 hour ago' '+%H')
[edvin]$ echo $prevhour
02
date's -d option not avaliable on some system.
I believe in that in your attempt the shell is considered the * as part of the variable prevhour as you did not put it into {} that separate variables from sorrunding text.
This is my working solution based by your attempt:
#!/bin/ksh
r_host='server2'
r_user='edvin'
l_dir='./content'
r_dir='./Test_folder'
# this still not cover the case of midnight
# it put 00 to 23 but day have to be yesterday as well
##vdate=$(TZ=bb24 date '+%Y%m%d')
##vhour=$(date '+%H') # not used
##prevhour=$(date -d '1 hour ago' '+%H')
# vtime = YYYYmmdd_HH -1 H
vtime=$(TZ=bb24 date -d '1 hour ago' '+%Y%m%d_%H')
sftp ${r_user}#${r_host} << EOF
lcd ${l_dir}
cd ${r_dir}
get filename_${vtime}*.dat
bye
EOF
exit
Output:
[edvin]$ ./script.ksh
Connected to server2.
sftp> lcd ./content
sftp> cd ./Test_folder
sftp> get filename_20190415_02*.dat
Fetching /home/edvin/Test_folder/filename_20190415_020000.dat to filename_20190415_020000.dat
Fetching /home/edvin/Test_folder/filename_20190415_020100.dat to filename_20190415_020100.dat
Fetching /home/edvin/Test_folder/filename_20190415_020200.dat to filename_20190415_020200.dat
Fetching /home/edvin/Test_folder/filename_20190415_020300.dat to filename_20190415_020300.dat
Fetching /home/edvin/Test_folder/filename_20190415_020400.dat to filename_20190415_020400.dat
Fetching /home/edvin/Test_folder/filename_20190415_020500.dat to filename_20190415_020500.dat
Fetching /home/edvin/Test_folder/filename_20190415_020600.dat to filename_20190415_020600.dat
Fetching /home/edvin/Test_folder/filename_20190415_020700.dat to filename_20190415_020700.dat
Fetching /home/edvin/Test_folder/filename_20190415_020800.dat to filename_20190415_020800.dat
Fetching /home/edvin/Test_folder/filename_20190415_020900.dat to filename_20190415_020900.dat
Fetching /home/edvin/Test_folder/filename_20190415_021000.dat to filename_20190415_021000.dat
sftp> bye
There is many thing can go wrong still in this solution,
like if remote directory not exist, not accessible, script will still go on with the rest of the command, same for the local directory and for the files as well. The connection also can run various problems you might want to handle. You like to schedule it so might a solution needed to avoid script spawn over and over again if one already run.
scp would be more preferred way to do this, as you use password less authentication.
If scp is not an option for some reason, with expect this can be handled quite well.

Text-Message Gateways & Incrementing Bash Variable Daily

I have a bash script that is sending me a text daily, for 100 days.
#! /bin/bash
EMAIL="my-phone-gateway#address.net"
MESSAGE="message_content.txt"
mail $EMAIL < $MESSAGE
Using crontab, I can have the static $MESSAGE sent to me every day.
Other than hard-coding 100 days of texts ;)
How could I implement a variable counter such that I can have my texts say:
"Today is Day #1" on the first day, "Today is Day #2" on the second day, etc. ?
Note: The location of the requested text within the $MESSAGE file doesn't matter. Last line, first line, middle, etc.
The only requirement for an answer here is that I know what day it is relative to the first, where the first day is the day the script was started.
Of course, bonus awesome points for the cleanest, simplest, shortest solution :)
For our nightly build systems, I wrote a C program that does the calculation (using local proprietary libraries that store dates as a number of days since a reference date). Basically, given a (non-changing) reference date, it reports the number of days since the reference date. So, the cron script would have a hard-wired first day in it, and the program would report the number of days since then.
The big advantage of this system is that the reference date doesn't change (very often), so the script doesn't change (very often), and there are no external files to store information in.
There probably are ways to achieve the same effect with standard Unix tools, but I've not sat down and worked out the portable solution. I'd probably think it terms of using Perl. (The C program only works up to 2999 CE; I left a note in the code for people to contact me about 50 years before it becomes a problem for the Y3K fix. It is probably trivial.)
You could perhaps work in terms of Unix timestamps...
Create a script 'days_since 1234567890' which treats the number as the reference date, gets the current time stamp (from date with appropriate format specification; on Linux, date '+%s' would do that job, and it works on Mac OS X too), takes the difference and divides by 86,400 (the number of seconds in a day).
refdate=1234567890
bc <<EOF
scale=0
($(date '+%s') - $refdate) / 86400
EOF
An example:
$ timestamp 1234567890
1234567890 = Fri Feb 13 15:31:30 2009
$ timestamp
1330027280 = Thu Feb 23 12:01:20 2012
$ refdate=1234567890
$ bc <<EOF
> scale=0
> ($(date '+%s') - $refdate) / 86400
> EOF
1104
$
So, if the reference date was 13th Feb 2009, today is day 1104. (The program bc is the calculator; its name has nothing to do with Anno Domini or Before Christ. The program timestamp is another homebrew of mine that prints timestamps according to a format that can be specified; it is a specialized variant of date originally written in the days before date had the functionality, by which I mean in the early 1980s.)
In a Perl one-liner (assuming you specify the reference date in your script):
perl -e 'printf "%d\n", int((time - 1234567890)/ 86400)'
or:
days=$(perl -e 'printf "%d\n", int((time - 1234567890)/ 86400)')
The only way to accomplish this would be to store the date in a file, and read from that file each day. I would suggest storing the epoch time.
today=$(date +%s)
time_file="~/.first_time"
if [[ -f $time_file ]]; then
f_time=$(< "$time_file")
else
f_time=$today
echo "$f_time" > "$time_file"
fi
printf 'This is day: %s\n' "$((($today - $f_time) / 60 / 60 / 24))"
Considering that your script is running only once a day, something like this should work:
#!/bin/bash
EMAIL="my-phone-gateway#address.net"
MESSAGE="message_content.txt"
STFILE=/tmp/start.txt
start=0
[ -f $STFILE ] && start=$(<$STFILE)
start=$((start+1))
MESSAGE=${MESSAGE}$'\n'"Today is Day #${start}"
echo "$start" > $STFILE
mail $EMAIL < $MESSAGE
A simple answer would be to export the current value to an external file, and read that back in again later.
So, for example, make a file called "CurrentDay.dat" that has the number 1 in it.
Then, in your bash script, read in the number and increment it.
e.g. your bash script could be:
#!/bin/bash
#Your stuff here.
DayCounter=$(<CurrentDay.dat)
#Use the value of DayCounter (i.e. $DayCounter) in your message.
DayCounter=$((DayCounter + 1))
echo $DayCounter > CurrentDay.dat
Of course, you may need to implement some additional checks to avoid something going wrong, but that should work as is.

Resources