I want schedule the cron job on every Monday and Thursday at 1.00 AM. I have used below command but I am getting an error.
0 1 * * Mon,Thu /home/abc/xyz.ksh
crontab: error on previous line; unexpected character found in line.
crontab: errors detected in input, no crontab file generated.
Can anyone advise me how to set it up?
Please try this instead:
0 1 * * 1,2 /home/abc/xyz.ksh >/dev/null 2>&1
Regards
0 1 * * 1,4 /home/abc/xyz.ksh >/dev/null 2>&1
Where 1 and 4 translates to Monday and Thursday respectively. Valid range is 0 to 6 with 0 being Sunday and 6 representing Saturday
Related
I have an awk script to print pids appearing in myfilename. Where myfilename contains a list of pids each one appearing on a new line...
ps -eaf | awk -f script.awk myfilename -
And here is the contents of script.awk...
# process the first file on the command line (aka myfilename)
# this is the list of pids
ARGIND == 1 {
pids[$0] = 1
}
# second and subsequent files ("-"/stdin in the example)
ARGIND > 1 {
# is column 2 of the ps -eaf output [i.e.] the pid in the list of desired
# pids? -- if so, print the entire line
if ($2 in pids)
printf("%s\n",$0)
}
At the moment the comman prints out pids in order of the ps -eaf command however I would like it to print out pids as per the order that they appear in myfilename.
I tried to modify the script to loop through $pids and repeat the same logic but I couldn't quite get it right.
Appreciate it if someone could help me with this.
thanks
Forgive my rusty AWK. Perhaps this is usable?
ARGIND == 1 {
pids[$0] = NR # capture the order
}
ARGIND > 1 {
if ($2 in pids) {
idx = pids[$2];
matches[idx] = $0; # capture the line and associate it with the ps -eaf order
if (idx > max)
max = idx;
}
}
END {
for(i = 1; i <= max; i++)
if (i in matches)
print matches[i];
}
I don't know what the output from ps -eaf looks like or what assumptions might be useful to exploit from its output. When I first read the question I thought OP had more than two inputs to the script. If it's really going to be only two then it probably makes more sense to reverse the inputs, if not then this might be the more general approach.
I would instead do this using the time-honoured NR==FNR construct. It goes a little something like this (one-liner).
ps -eaf | awk 'NR==FNR{p[$1]++;next} $2 in p' mypidlist -
The idea of NR==FNR is we look at the current record number (NR), and compare it to the record number within the current file (FNR). If they are the same, we are in the same file, so we store a record and move to the next line of input.
If NR==FNR is not true, then we simply check for $2 being in the array.
So the first expression populates the array p[] with the contents of mypidlist, and the second construct is a condition only, which defaults to {print} as its statement.
Of course, the one-liner above does not address your requirement to print results in the order of your pid input file. To do that, you need to keep an index and record the data in an array for some kind of sort. Of course, it doesn't have to be a real sort, just keeping the index itself should be sufficient. The following is a bit long as a one-liner:
ps -eaf | awk 'NR==FNR{p[$1]++;o[++n]=$1;next} $2 in p {c[$2]=$0} END {for(n=1;n<=length(o);n++){print n,o[n],c[o[n]]}}' mypidlist -
Broken out for easier reading, the awk script looks like this:
# Record the pid list...
NR==FNR {
p[$1]++ # Each pid is an element in this array.
o[++n]=$1 # This array records the order of the pids.
next
}
# If the second+ input source has a matching pid...
$2 in p {
c[$2]=$0 # record the line in a third array, pid as key.
}
END {
# At the end of our input, step through the ordered pid list...
for (n=1;n<=length(o);n++) {
print c[o[n]] # and print the collected line, using our pid index as key.
}
}
Note that in the event a pid from your list is missing from ps output, the result will be to print a blank line, since awk doesn't complain about references to nonexistent array indices.
Note also that length(arrayname) notation works in GAWK and OneTrueAwk, but may not be universal. If that doesn't work for you, you might be able to add an something like this to your awk script:
function alength(arrayname, i, n) {
for(i in arrayname)
n++
return n
}
If there is one file, you can flip the order of inputs and use idiomatic awk as follows
$ awk 'NR==1; NR==FNR{a[$2]=$0;next} $0 in a{print a[$0]}' <(ps -eaf) <(seq 10)
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 02:36 ? 00:00:03 /sbin/init
root 2 0 0 02:36 ? 00:00:00 [kthreadd]
root 3 2 0 02:36 ? 00:00:00 [ksoftirqd/0]
root 4 2 0 02:36 ? 00:00:00 [kworker/0:0]
root 5 2 0 02:36 ? 00:00:00 [kworker/0:0H]
root 6 2 0 02:36 ? 00:00:00 [kworker/u30:0]
root 7 2 0 02:36 ? 00:00:00 [rcu_sched]
root 8 2 0 02:36 ? 00:00:00 [rcuos/0]
root 9 2 0 02:36 ? 00:00:00 [rcuos/1]
root 10 2 0 02:36 ? 00:00:00 [rcuos/2]
Here, the list of the ids provided by the seq, substitute with your file.
I asked this question here before and I went using this code for the job. The issue is that the cron job ran, but it should only run on Fridays, instead it ignored the "5" for Friday and ran on 06/26 (correct), 06/27-06/28-06/29 and 06/30. Can anyone suggest the reason why it ignored the "5" for Friday and still ran for all the dates in the range and how it can be fixed?
0 1 25-31 1,3,5,7,8,10,12 5 code.pl
0 1 24-30 4,6,9,11 5 code.pl
0 1 22-28 2 5 code.pl
Thanks for looking!
See this answer for something very similar
https://superuser.com/questions/348348/crontab-day-of-week-vs-day-of-month
When you specify both day-of-the-week and day-of-the-month is will run when either are true.
You would need to use the cron time/date settings, and add a condition to the command, such as:
0 1 22-28 2 * test $(date +%a) = "Fri" && code.pl
Help needed. I want to increment Date (which is a string) column in csv by one day.
e.g. (Date Format yyyy-MM-dd)
Col1,Col2,Col3
ABC,001,1900-01-01
XYZ,002,2000-01-01
Expected OutPut
Col1,Col2,Col3
ABC,001,1900-01-02
XYZ,002,2000-01-02
There's one standard Unix utility that has all the date magic from September 14, 1752 through December 31, 9999 built-in: the calendar cal. Instead of reinventing the wheel and do messy date calculations we will use its intelligence to our advantage. The basic problem is: given a date, is it the last day of a month? If not, simply increment the day. If yes, reset day to 1 and increment month (and possibly year).
However, the output of cal is unspecified and it may look like this:
$ cal 2 1900
February 1900
Su Mo Tu We Th Fr Sa
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28
What we would need is a list of days, 1 2 3 ... 28. We can do this by skipping everything up to the "1":
set -- $(cal 2 1900)
while test $1 != 1; do shift; done
Now the number of args gives us the number of days in February 1900:
$ echo $#
28
Putting it all together in a script:
#!/bin/sh
read -r header
printf "%s\n" "$header"
while IFS=,- read -r col1 col2 y m d; do
case $m-$d in
(12-31) y=$((y+1)) m=01 d=01;;
(*)
set -- $(cal $m $y)
# Shift away the month and weekday names.
while test $1 != 1; do shift; done
# Is the day the last day of a month?
if test ${d#0} -eq $#; then
# Yes: increment m and reset d=01.
m=$(printf %02d $((${m#0}+1)))
d=01
else
# No: increment d.
d=$(printf %02d $((${d#0}+1)))
fi
;;
esac
printf "%s,%s,%s-%s-%s\n" "$col1" "$col2" $y $m $d
done
Running it on this input:
Col1,Col2,Col3
ABC,001,1900-01-01
ABC,001,1900-02-28
ABC,001,1900-12-31
XYZ,002,2000-01-01
XYZ,002,2000-02-28
XYZ,002,2000-02-29
yields
Col1,Col2,Col3
ABC,001,1900-01-02
ABC,001,1900-03-01
ABC,001,1901-01-01
XYZ,002,2000-01-02
XYZ,002,2000-02-29
XYZ,002,2000-03-01
I made one little assumption: The first two columns don't contain a - or escaped comma. If they do, the IFS=,- read will act up.
Using the date command, this can be done in awk:
awk 'BEGIN{FS=OFS=","}NR>1{("date -d\""$3" +1 day\" +%Y-%m-%d")|getline newdate; $3=newdate; print}' file.in
If you can extract the date from the file, you can use this:
d="1900-01-01" # date from file
date --date '#'$(( $(date --date $d +"%s") + 86400 ))
I need unix cron command to run every 12 hours.
I have 500+ sub blogs in my server.
This is the file i want to run every 12 hours
http://*.mysite.com/somedir/index.php
Where * is my subdomain of my blogs.
I need cron command for all blogs.
Is it possible to run all of them with single command?
OR do i have to create command for each blog?
A crontab file has five fields for specifying day , date and time followed by the command to be run at that interval.
* * * * * command to be executed
- - - - -
| | | | |
| | | | +----- day of week (0 - 6) (Sunday=0)
| | | +------- month (1 - 12)
| | +--------- day of month (1 - 31)
| +----------- hour (0 - 23)
+------------- min (0 - 59)
* in the value field above means all legal values as in braces for that column.
You could use 0 1,13 * * * which means for every 1AM and 1PM.
0 1,13 * * * rm /var/www/*/somedir/index.php > /home/someuser/cronlogs/some.log 2>&1
where * can be replaced by different domain names.
I think the right way is -> 1 */12 * * * (actually, any number in the minute position will do the trick.)
If you set -> * */12 * * * it will be executed every minute at 12h and again at 24h.
Assuming your sites live in /var/www/sitename and you have the php shell installed in /usr/bin/php you can easily create a cron job that runs all those files.
run
crontab -e
and add this line
42 */12 * * * /usr/bin/php /var/www/*/somedir/index.php >> ~/cronjob.log 2>&1
The * here in /var/www/*/somedir is just a wildcart. This means it will catch every directory in your /var/ww folder.
f.ex:
[jens#localhost ~]$ ls -l temp
total 28
-rw-rw-r--. 1 jens jens 1641 Feb 21 16:12 somefile.py
drwxrwxr-x. 2 jens jens 4096 Feb 22 15:10 test
drwxrwxr-x. 2 jens jens 4096 Feb 22 15:10 test2
drwxrwxr-x. 2 jens jens 4096 Feb 22 15:10 test3
drwxr-xr-x. 8 jens jens 4096 Jan 27 10:21 emptydir
-rw-rw-r--. 1 jens jens 548 Jan 27 16:15 Unsaved Document 1
[jens#localhost ~]$ ls temp/*/testfile.php
temp/test2/testfile.php temp/test3/testfile.php temp/test/testfile.php
As you can see, this returns the testfile.php in each subfolder of temp, namely folder test, test2 and test3.
Emptydir is also a folder, but since it has no testfile.php in it, nothing willhappen with it.
If your directory structure is arbitrarily deep you can use **
e.g.
42 */12 * * * /usr/bin/php /var/www/**/index.php >> ~/cronjob.log 2>&1
Use "*/12" to mean "every 12 hours."
You need some kind of master-script (called by cron), which expands the list of sites, and calls "/usr/bin/php /var/www/*/somedir/index.php", whith the '*' replaced by a list entry. This can be done in a shellscript, a perl or python script, or maybe even a php script. For sh this could be: (untested)
#!/bin/sh
cd /home/subdir/for/cron
LIST="a b c d e f g h i j k l m o p q r s t u v w x y z"
for x in $LIST; do
/usr/bin/php /var/www/${x}/somedir/index.php 2>$1 > /tmp/${x}.log
done
If it is inconvenient to have the list hardcoded like this, there are other methods:
backticks, or read < file_with_all_the_names_in_it
0 */12 * * * means "At minute 0 past every 12th hour."
Check out https://crontab.guru for a nice calculator.
Write command in console
crontab -e
edit with editor (I like nano)
add line
0 1,13 * * * php /home/catalog/public_html/crons/index.php
close with
press ctrl + x
press y then press enter
done :)
Check if saved with
crontab -l
command
if you want to test if it will work test just running it manualy with
php /home/catalog/public_html/crons/index.php
command
Use this it will Run after each 12 hour
* */12 * * * php /var/www/"Your domain"/cronfile.php
->cron('0 */12 * * *');
This cron will run the scheduler at every 12 hours.
I am trying to find a file that are 0 days old. Below are the steps I performed to test this
$ ls
$ ls -ltr
total 0
$ touch tmp.txt
$ ls -ltr
total 0
-rw-r----- 1 tstUser tstUser 0 Feb 28 20:02 tmp.txt
$ find * -mtime 0
$
$ find * -mtime -1
tmp.txt
$
Why is '-mtime 0' not getting me the file?
What is the exact difference between '-mtime 0' and '-mtime -1'?
Im sure there must be other ways to find files that are 0 days old in unix, but im curious in understanding how this '-mtime' actually works.
This is a not user friendly aspect of find - you have to understand how the matching actually works to correctly define your search criteria. The following explanation is based on GNU find (findutils) 4.4.2.
find tests -atime, -ctime, -mtime work on 24 hour periods, therefore let's define "file age" as
floor (current_timestamp - file_modification_timestamp / 86400)
Given three files modified 1 hour ago, 25 hours ago and 49 hours ago
$ touch -t $(date -d "1 hour ago" +"%m%d%H%M") a.txt
$ touch -t $(date -d "25 hours ago" +"%m%d%H%M") b.txt
$ touch -t $(date -d "49 hours ago" +"%m%d%H%M") c.txt
file ages (as defined above) are
$ echo "($(date +"%s") - $(stat -c %Y a.txt)) / 86400" | bc
0
$ echo "($(date +"%s") - $(stat -c %Y b.txt)) / 86400" | bc
1
$ echo "($(date +"%s") - $(stat -c %Y c.txt)) / 86400" | bc
2
Given the above, here's what find does
$ find -type f -mtime 0 # find files with file age == 0, i.e. files modified less than 24 hours ago
./a.txt
$ find -type f -mtime -1 # find files with file age < 1, i.e. files modified less than 24 hours ago
./a.txt
$ find -mtime 1 # find files with file age == 1, i.e. files modified more than (or equal to) 24 hours ago, but less than 48 hours ago
./b.txt
$ find -mtime +1 # find files with file age > 1, i.e. files modified more than 48 hours ago
./c.txt
This shows that -mtime 0 and -mtime -1 give equivalent results.
-mmin gives the same test with finer granularity - argument is minutes instead of 24 hour periods.
I'm unable to reproduce your problem using the aforementioned version of find
$ touch tmp.txt
$ find * -mtime 0
tmp.txt
$ find * -mtime -1
tmp.txt
-mtime n
File's data was last modified n*24 hours ago. See the comments
for -atime to understand how rounding affects the interpretation
of file modification times.
So, -mtime 0 would be equal to: "File's data was last modified 0 hours ago.
While -mtime 1 would be: "File's data was last modified 24 hours ago"
Edit:
Numeric arguments can be specified as
+n for greater than n,
-n for less than n,
n for exactly n.
So I guess -1 would be modified within the last 24 hours, while 1 would be exactly one day.
The meaning of those three possibilities are as following:
n: exactly n 24-hour periods (days) ago, 0 means today.
+n: "more then n 24-hour periods (days) ago", or older then n,
-n: less than n 24-hour periods (days) ago (-n), or younger then n. It's evident that -1, and 0 are the same and both means "today".
NOTE: If you use parameters with find command in scripts be careful when -mtime parameter is equal zero. Some (earlier) versions of GNU find incorrectly interpret the following expression
Sourece: http://www.softpanorama.org/Tools/Find/index.shtml