Hide default command line output from 'at' - command

I was wondering how I would suppress the following output.
commands will be executed using /bin/ksh
job ##########.a at Mon Mar ## ##:##:## 2014
when using the "at - k" command. I have tried using it like
at -k "now + 5 hours" <<! >/dev/null
something
!
but I keep getting the output. Any suggestions?

at writes to stderr, not to stdout.
To redirect both, use the following:
at -k "now + 5 hours" <<! >/dev/null 2>&1
something
!
The 2>&1 tells the shell to redirect file descriptor 2 (stderr) to the same file as fd 1 (stdout).

Related

How to replace date -d from script running on Linux to get it working on AIX

On a Linux system I'm running a bash script what is running fine, but now I want to use the same script on an AIX system.
Only a small part of it isn't able to run because on the AIX system the command "date -d" is not working.
Below is the code that is running on the linux server, baised on the hostname in this case system1 and system2 a script will run only on a Sunday at the given time.
declare -A myservertime
myservertime["system1"]="02:00"
myservertime["system2"]="02:10"
for keys in "${!myservertime[#]}";
do
if [[ "$keys" == "$HOSTNAME" ]]; then
mylaunchtime=${myservertime["$keys"]}
fi
done
if [ -z "$mylaunchtime" ]; then
echo "Server not found."
exit
fi
timenow=$(date +"%s")
weekday=$(date +"%a" -d #$timenow )
timerun=$(date +"%s" -d ${mylaunchtime} )
if [ $timerun -lt $timenow ]; then
timerun=$(( timerun + 86400 ))
fi
sleep_time=$(( timerun - timenow ))
#Check is weekday = Sunday
if [ $weekday == "Sun" ]; then
#If Sunday then wait until starttime is reached, until then sleep
sleep $sleep_time
#If starttime is reached execute startprogram
startprogram
fi
I already fixed the declare part, this is also not working on AIX, to the following:
typeset -A myservertime=(["pvm00066"]="02:30" ["pvm00100"]="01:30")
But I have troubles to get the variables $weekday and $timerun working, because of that "date -d $variable"
Anyone here that can help me with this, I tried and searched all kind of stuff but I was unable to get one working.
When you do want to have an identical crontab and script on all systems, and you only want to run the script on Sunday, just use an offset from 00:00.
Crontab:
0 0 * * 7 start_with_delay.sh
start_with_delay.sh:
declare -A myservertime
myserversleep["system1"]=7200
myserversleep["system2"]=7800
sleep ${myserversleep[HOSTNAME]}
startprogram
When you do not need fixed starting times for the different hosts, but only want different hosts to have different starting times, you can consider using the the last number of the IP as an input for calculating the sleep time.
Two reasons why you might consider another solution:
Starting a job with crontab, that starts with sleeping, is very confusing.
An operator reading the crontab expects something to start at the time given in the crontab.
Using a scriptname like sleep_and_start helps a little.
When the system reboots at Sunday 01:00, nothing is started at 02:00
The sleep command has been stopped during the reboot.
I would try to find a smart install script, that will write a different crontab on each host. Something with Ansible, a Puppet template or shellscript.
case $HOSTNAME in
system1)
starthour=2
startminute=0
;;
system2)
starthour=2
startminute=10
;;
*)
echo "No scheduled startprogram on ${HOSTNAME}.
exit 0
;;
esac
echo "${startminute} ${starthour} * * SUN startprogram" | crontab -
When you want to update en existing crontab, you might want something like
(crontab -l 2>/dev/null && echo "${startminute} ${starthour} * * 7 startprogram") |
sort -u | crontab -

How to use the "run this command" (-rc) option with logman

I'm trying to set up some performance monitors. I also want to do some stuff with the data (csv), including analyzing the data with some PS scripting upon collection segmentation. Here is my PS command to create the logman entry:
logman create counter -n NetLog -f csv -si 00:00:30 `
-cnf 00:01:00 -c "\Network Interface(*)\Bytes Total/sec" -r -v mmddhhmm `
-b 00:00:00 -e 23:59:59 -rc C:\PerfLogs\Admin\NetLogConfig\hello.cmd
Note that the details like segment length and sample interval are only that low for testing purposes. Production will be much different, though undecided as of yet, but I digress. Now, this works great:
logman create counter -n NetLog -f csv -si 00:00:30 `
-cnf 00:01:00 -c "\Network Interface(*)\Bytes Total/sec" -r -v mmddhhmm `
-b 00:00:00 -e 23:59:59
But for some reason, as soon as I add -rc C:\PerfLogs\Admin\NetLogConfig\hello.cmd, the counter stops upon segmentation of the collection period instead of segmenting and continuing. Note that the command to create the counter succeeds, and the counter will start successfully, but the collector set is halted when the file is closed for segmentation. It also does not run the command at all. I have also tried a file type of .bat instead of .cmd, and I have also tried typing a command directly into the -rc parameter (eg -rc echo "Hello World!"). .bat makes no difference, and enetering a command directly will get me a nice error message about it not being an acceptable paramater. Inside the file is a place-holder command that right now goes:
echo "Hello World!"
pause
So how do I get a command to run upon segmentation/file close? I will consider work-arounds, but this seems by far the cleanest solution.
Read newest logman create counter reference:
-[-]rc <task> Run the command specified each time the log is closed.
Note that -rc switch parameter is -rc <task> (in an older Technet document is -rc FileName). So what <task> stands for? Read Data Collector Set Properties and/or run perfmon.exe, see image below:
Task - You can run a Windows Management Instrumentation (WMI) task upon completion
of the Data Collector Set collection by entering the command in the
Run this task when the data collector set stops box.
Refer to WMI task documentation for options.
And finally, from WMI task documentation I have recognized that <task> in -rc <task> should be a name of a scheduled task. Next modification of your attempt might give a proof (a new instance of cmd window flashes every minute and output files are filled as expected):
erase d:\bat\SO\38859079.txt
erase C:\PerfLogs\Admin\NetLog*.csv
logman delete NetLog
logman create counter -n NetLog -f csv -si 00:00:15 -cnf 00:01:00 ^
-rf 00:05:00 -c "\Network Interface(*)\Bytes Total/sec" -r -v mmddhhmm ^
-b 00:00:00 -e 23:59:59 -rc 38859079
logman start NetLog
timeout /T 360 /Nobreak
logman stop NetLog
dir /B /S C:\PerfLogs\Admin\NetLog*.csv
type d:\bat\SO\38859079.txt
Schtasks /Query /FO LIST /V /TN 38859079 | findstr /I /C:"Task To" /C:"Type"
Output:
==> D:\bat\SO\38859079.bat
==> erase d:\bat\SO\38859079.txt
==> erase C:\PerfLogs\Admin\NetLog*.csv
==> logman delete NetLog
The command completed successfully.
==> logman create counter -n NetLog -f csv -si 00:00:15 -cnf 00:01:00 -rf 00:05:00 -c "\
Network Interface(*)\Bytes Total/sec" -r -v mmddhhmm -b 00:00:00 -e 23:59:59 -rc 388590
79
The command completed successfully.
==> logman start NetLog
The command completed successfully.
==> timeout /T 360 /Nobreak
Waiting for 0 seconds, press CTRL+C to quit ...
==> logman stop NetLog
Error:
Data Collector Set is not running.
==> dir /B /S C:\PerfLogs\Admin\NetLog*.csv
C:\PerfLogs\Admin\NetLog_08101250.csv
C:\PerfLogs\Admin\NetLog_08101251.csv
C:\PerfLogs\Admin\NetLog_08101252.csv
C:\PerfLogs\Admin\NetLog_08101253.csv
C:\PerfLogs\Admin\NetLog_08101254.csv
==> type d:\bat\SO\38859079.txt
10.08.2016 12:51:47,99
10.08.2016 12:52:49,04
10.08.2016 12:53:50,06
10.08.2016 12:54:51,07
10.08.2016 12:55:48,00
==> Schtasks /Query /FO LIST /V /TN 38859079 | findstr /I /C:"Task To" /C:"Type"
Task To Run: cmd /c >>d:\bat\SO\38859079.txt echo %date% %time%
Schedule Type: On demand only
==>
Please note than your question has nothing to do with powershell (IMHO wrong tag); in my example is scheduled task to run cmd however it should work for powershell as well.

Msys: how to keep STDERR on the screen and at the same time copy both STDOUT and STDERR to files

I would like to be able to
Display STDERR on the screen
Copy STDOUT and STDERR in files (and if possible in the same file)
For information, I am using Msys to do that.
.
After doing some research on the SO, I have tried to use something like
<my command> > >(tee stdout.log) 2> >(tee stderr.log)
Bu I got the following error:
sh: syntax error near unexpected token `>'
.
Any idea on how to do that?
There might be no direct solution in Msys but the >(tee ... ) solution works fine in *Nix, OSX, and probably Cygwin.
The workaround is to grep all the errors and warnings we want to keep them on the screen.
I have successfully used the following command for a makefile to compile C code:
make 2>&1 | tee make.log | grep -E "(([Ee]rror|warning|make):|In function|undefined)"
I have a simple script (test.sh) that generates STDOUT and STDERR:
#!/bin/bash
echo hello
rm something
exit
Then, to do what you want execute with the following:
./test.sh > stdout.log 2> >(tee stderr.log >&2)
You'll get the STDERR on the screen, and two separated log files with STDERR and STDOUT. I used part of the answer given here
Note that I am assuming you don't have a file called something on the current directory :)
If you want both STDOUT and STDERR to go to the same file, use the -a option on tee:
./test.sh > std.log 2> >(tee -a std.log >&2)

How to capture error message from prompt - shell or perl

I am trying to capture the output of a command. It works fine if the command executes. However when there is an error, i am unable to capture what gets displayed in commandline
Eg.
$ out=`/opt/torque/bin/qsub submitscript`
qsub: Unauthorized Request MSG=group ACL is not satisfied: user abc#xyz.org, queue home
$ echo $out
$
I want $out to have the message
Thanks!
Errors are on stderr, so you need to redirect them into stdout so the backticks will capture it:
out=`/opt/torque/bin/qsub submitscript 2>&1`
if [ $? -gt 0 ] ; then
# By convention, this is sent to stderr, but if you need it on
# stdout, just remove the >&2 redirection
echo "Error: $out" >&2
else
echo "Success: $out"
fi
You should test the exit status of the command to figure out what the output represents (one way shown). It is similar for perl, slightly different syntax of course.
Have you tried doing it like this
$ out=`/opt/torque/bin/qsub submitscript 2>&1 > /dev/null`
$ echo $out

tail and grep log and mail (linux)

i want to tail log file with grep and sent it via mail
like:
tail -f /var/log/foo.log | grep error | mail -s subject name#example.com
how can i do this?
You want to send an email when emailing errors occur? That might fail ;)
You can however try something like this:
tail -f $log |
grep --line-buffered error |
while read line
do
echo "$line" | mail -s subject "$email"
done
Which for every line in the grep output sends an email.
Run above shell script with
nohup ./monitor.sh &
so it will keep running in the background.
I'll have a go at this. Perhaps I'll learn something if my icky bash code gets scrutinised. There is a chance there are already a gazillion solutions to do this, but I am not going to find out, as I am sure you have trawled the depths and widths of the cyberocean. It sounds like what you want can be separated into two bits: 1) at regular intervals obtain the 'latest tail' of the file, 2) if the latest tail actually exists, send it by e-mail. For the regular intervals in 1), use cron. For obtaining the latest tail in 2), you'll have to keep track of the file size. The bash script below does that - it's a solution to 2) that can be invoked by cron. It uses the cached file size to compute the chunk of the file it needs to mail. Note that for a file myfile another file .offset.myfile is created. Also, the script does not allow path components in the file name. Rewrite, or fix it in the invocation [e.g. (cd /foo/bar && segtail.sh zut), assuming it is called segtail.sh ].
#!/usr/local/bin/bash
file=$1
size=0
offset=0
if [[ $file =~ / ]]; then
echo "$0 does not accept path components in the file name" 2>&1
exit 1
fi
if [[ -e .offset.$file ]]; then
offset=$(<".offset.$file")
fi
if [[ -e $file ]]; then
size=$(stat -c "%s" "$file") # this assumes GNU stat, possibly present as gstat. CHECK!
# (gstat can also be Ganglias Status tool - careful).
fi
if (( $size < $offset )); then # file might have been reduced in size
echo "reset offset to zero" 2>&1
offset=0
fi
echo $size > ".offset.$file"
if [[ -e $file && $size -gt $offset ]]; then
tail -c +$(($offset+1)) "$file" | head -c $(($size - $offset)) | mail -s "tail $file" foo#bar
fi
How about:
mail -s "catalina.out errors" blah#myaddress.com < grep ERROR catalina.out