using time command in bash script and redirect the output - bash

I'm trying to write a script that does
x =$ncore
numactrl -C $x ( time -p $exe ) > out.txt 2>&1
on the terminal ( time $ exe ) > out.txt 2>&1 worked as i wanted to (out.txt containing output of time and executable )
i'm using red hat 6.2 and time is not GNU version( i'm assuming from the fact that -a -o options don't work)
i want out.txt to have output from the executable and at the end have output from the time command.
the bash script is giving me problems with having ( so i used ( time -p $exe ) and now numactl sees ( as the executable.
is there a way to use numactl and time command together and have the output i want ?

If numactrl wants a command, but you want to use some shell features, just give it the shell as a command:
numactrl -C $x bash -c "( time -p $exe ) > out.txt 2>&1"
When you runtime -p $exe from a bash prompt or within a bash -c, you're using the bash builtin version of time. The one with the -o option is an external command, so to use it from bash you have to specify command time or /bin/time or /usr/bin/time.
If you run numactrl -C $x time ... then it probably runs the external command, so -o should work in that case, but if not then you always have the bash -c method.
Note that the output format is different between the various versions of time. The GNU coreutils version prints more information than the bash builtin version.

Related

Suppress output of a command while recording output from "time"

I have some command which launches in this way:
./mycommand -arg=word
I measure execution time and write output to file:
/usr/bin/time -f "%K %e" ./mycommand -arg=word 2>file
However, mycommand has also stderr output. So file contains mixed data from both (time and mycommand). How can I suppress mycommand output and save time data?
If the nature of your process is such that a shell startup won't interfere with the timing too much, one simple approach is to have a shell run the direction as a subprocess of time:
/usr/bin/time -f "%K %e" sh -c '"$0" "$#" >/dev/null 2>&1' ./mycommand -arg=word
I would also suggest using the bash-builtin version of time instead of the external one, which lets you use tricks documented in BashFAQ #32:
TIMEFORMAT='%R' # replace for whatever is equivalent to your "%K %e"
timing=$(time { ./mycommand >/dev/null 2>&1; } 2>&1)

Writing a script that runs a command and times it

I'm trying to write a script that will run and time a given and output that to a file in a .csv format.
So far from looking at SO previous posts, I've found that sh -c "$index_of_command_arg" can be used to invoke that command.
I'm also familiar with time and I know that people use /usr/bin/time for formatting, but I need to format the time given in total seconds (for example, 1.34516) but the only given option to format the real time is %E which return [hours:]minutes:seconds. Is there any way to format it the way I need?
The general idea of my script is:
# ----
# some input validation
# ----
rule=$1
command=$2
execution_time=/usr/bin/time -f "%total_seconds" sh -c "$command" #is this line possible?
echo "$rule,$execution_time" > output_file.csv
Can this be formatted the way I want? and also, the line with the comment after it,
Will this even work the way I wrote it? is the syntax correct?
Say I use the normal time and I get the real 0m2.003 ...
output, how can I take the 2.003 out of it?
The normal time you are mentioning is the bash built-in time. From the Bash Reference Manual:
The TIMEFORMAT variable may be set to a format string
that specifies how the timing information should be displayed.
…
%[p][l]R
The elapsed time in seconds.
So, you could use
execution_time=`TIMEFORMAT=%R bash -c "time $command" 2>&1 >/dev/tty`
You replace:
execution_time=/usr/bin/time -f "%total_seconds" sh -c "$command" `
with:
execution_time=`(time sh -c "$command > /dev/null 2>&1") 2>&1 | grep real |sed "s/.*m//;s/s.*//;"`
or with:
execution_time=`(time sh -c "$command > /dev/null 2>&1") 2>&1 | grep real | cut -c 8-12`
Why > /dev/null - you don't want to see $command output 2>&1 (STDERR > STDOUT)
Why 2>&1 for time command (for the same reason as in previous bullet)

How to hide output error messages from terminal? [duplicate]

I have a Bash script that runs a program with parameters. That program outputs some status (doing this, doing that...). There isn't any option for this program to be quiet. How can I prevent the script from displaying anything?
I am looking for something like Windows' "echo off".
The following sends standard output to the null device (bit bucket).
scriptname >/dev/null
And if you also want error messages to be sent there, use one of (the first may not work in all shells):
scriptname &>/dev/null
scriptname >/dev/null 2>&1
scriptname >/dev/null 2>/dev/null
And, if you want to record the messages, but not see them, replace /dev/null with an actual file, such as:
scriptname &>scriptname.out
For completeness, under Windows cmd.exe (where "nul" is the equivalent of "/dev/null"), it is:
scriptname >nul 2>nul
Something like
script > /dev/null 2>&1
This will prevent standard output and error output, redirecting them both to /dev/null.
An alternative that may fit in some situations is to assign the result of a command to a variable:
$ DUMMY=$( grep root /etc/passwd 2>&1 )
$ echo $?
0
$ DUMMY=$( grep r00t /etc/passwd 2>&1 )
$ echo $?
1
Since Bash and other POSIX commandline interpreters does not consider variable assignments as a command, the present command's return code is respected.
Note: assignement with the typeset or declare keyword is considered as a command, so the evaluated return code in case is the assignement itself and not the command executed in the sub-shell:
$ declare DUMMY=$( grep r00t /etc/passwd 2>&1 )
$ echo $?
0
Try
: $(yourcommand)
: is short for "do nothing".
$() is just your command.
Like andynormancx' post, use this (if you're working in an Unix environment):
scriptname > /dev/null
Or you can use this (if you're working in a Windows environment):
scriptname > nul
This is another option
scriptname |& :
Take a look at this example from The Linux Documentation Project:
3.6 Sample: stderr and stdout 2 file
This will place every output of a program to a file. This is suitable sometimes for cron entries, if you want a command to pass in absolute silence.
rm -f $(find / -name core) &> /dev/null
That said, you can use this simple redirection:
/path/to/command &>/dev/null
In your script you can add the following to the lines that you know are going to give an output:
some_code 2>>/dev/null
Or else you can also try
some_code >>/dev/null

Append operator in bash shell

While running a bash shell script which contains this command:
iperf -c $server_ip -p $iperf_port -t $iperf_duration >> outputfile
the output is many times displayed on console rather than getting appended in the outputfile. Any solutions for same? Am I doing anything wrong?
I am using Ubuntu 12.04
I'm not familiar with iperf, but presumably it's writing some or all of its output to standard-error rather than to standard-output. To merge standard-error with standard-output and send them both to your file, you can add 2>&1 to the end:
iperf -c $server_ip -p $iperf_port -t $iperf_duration >> outputfile 2>&1

How to time a vim session using 'time'

I'm trying to log the time I spend working in vim. I've got a script that works with gvim but when I try to set it up with vim it locks up the terminal session silently or with the message 'Vim: Warning: Output is not to a terminal'
Here is the script that works with gvim:
#!/bin/sh
workfile="/home/na/writing/fiction.txt"
worklog="/home/na/writing/worktime.log"
d=`date --rfc-3339 date`
t=$( { /usr/bin/time -f "%e" /usr/local/bin/gvim -f -S /home/na/.vim/writeroom/writeroom.vim $workfile; } 2>&1 )
w=`wc -w $workfile`
echo $d $t $w >> $worklog
When I close the gvim window I get a logfile containing a date, the number of seconds I spent editing the file, and a word count for the file.
2011-08-15 700.15 238869 /home/na/writing/fiction.txt
I would like the same using vim in a terminal session.
I understand vim talks to the terminal directly instead of to stdout but I don't care about what vim returns, I want the output from the time command.
These don't work:
t=`/usr/bin/time -f "%e" /usr/local/bin/vim -f $workfile`
t=$( { /usr/bin/time -f "%e" /usr/local/bin/vim -f $workfile; } 2>&1 )
t=$( { /usr/bin/time -f "%e" /usr/local/bin/vim -f $workfile; } )
I suspect there's some combination of backticks and paranthesis that will make this work but I haven't stumbled onto it yet.
The backtick or $() operators capture vim's output (what you see on the terminal when opening vim is vim's output from its stdout), so you can't do that.
You could try this instead:
start=$(date +%s)
/usr/local/bin/vim -f $workfile
end=$(date +%s)
duration=$((end-start))
echo "$duration"
Some versions of time (eg: GNU's) support a flag to set the output file. eg:
/usr/bin/time -o /tmp/foo vim
If you're using bash you'll need to use the path for time (or a leading \) as bash has a reserved word time which behaves similar to the time command (but operates on an entire pipeline) that does not support the -o flag.

Resources