Using time ls, I have the following output:
$ time ls -l
total 2
-rwx------+ 1 FRIENDS None 97 Jun 23 08:59 location.txt
-rw-r--r--+ 1 FRIENDS None 10 Jun 23 09:06 welcome
real 0m0.040s
user 0m0.000s
sys 0m0.031s
Now, when I try to grep only the real value line, the actual result is:
$ time ls -l | grep real
real 0m0.040s
user 0m0.000s
sys 0m0.031s
My question is, how to get only the real value as output? In this case, 0m0.040s.
time writes its output to stderr, so you need to pipe stderr instead of stdout. But it's also important to remember that time is part of the syntax of bash, and it times an entire pipeline. Consequently, you need to wrap the pipeline in braces, or run it in a subshell:
$ { time ls -l >/dev/null; } 2>&1 | grep real
real 0m0.005s
With Bash v4.0 (probably universal on Linux distributions but still not standard on Mac OS X), you can use |& to pipe both stdout and stderr:
{ time ls -l >/dev/null; } |& grep real
Alternatively, you can use the time utility, which allows control of the output format. On my system, that utility is found in /usr/bin/time:
/usr/bin/time -f%e ls -l >/dev/null
man time for more details on the time utility.
(time ls -l) 2>&1 > /dev/null |grep real
This redirects stderr (which is where time sends its output) to the same stream as stdout, then redirects stdout to dev/null so the output of ls is not captured, then pipes what is now the output of time into the stdin of grep.
If you just want to specify the output format of time builtin, you can modify the value of TIMEFORMAT environment variable instead of filtering it with grep.
In you case,
TIMEFORMAT=%R
time ls -l
would give you the "real" time only.
Here's the link to relevant information in Bash manual (under "TIMEFORMAT").
This is a similar question on SO about parsing the output of time.
Look out.. bash has a built-in "time" command. Here are some of the differences..
# GNU time command (can also use $TIMEFORMAT variable instead of -f)
bash> /usr/bin/time -f%e ls >/dev/null
0.00
# BASH built-in time command (can also use $TIME variable instead of -f)
bash> time -f%e ls >/dev/null
-f%e: command not found
real 0m0.005s
user 0m0.004s
sys 0m0.000s
I think, it can be made a little easier:
time ls &> /dev/null | grep real
Related
I'm using "strace -f -T -tt -o foo.txt -p 1234" to print the time spent in system calls. This makes the output file huge, is there a way to just print the system calls that took greater than 1second. I can grep it out from the file later, but is there a better way?
If we simply omit the -o foo.txt argument, the output goes to standard output. We can pipe it through grep and redirect to the file:
strace -f -T -tt -p 1234 | grep pattern > foo.txt
To watch the output at the same time:
strace -f -T -tt -p 1234 | grep pattern | tee foo.txt
If a command prints only to a file that is passed as an argument, and we want to filter/redirect its output, the first step is to check whether it implements the dash convention: can you specify standard input or output using - as a filename argument:
some_command - | our_pipe > file.txt
If not, then the recourse is to use Bash process substitution substitution syntax: >(output command) and <(input command):
some_command >(our_pipe > file.txt)
The process substitution syntax expands into a token that is suitable as a filename argument for a command or function. When the program opens that token, it gets a file descriptor to the command's input or output, depending on direction.
With process substitution, we can redirect the input or output of stubborn programs which work only with files passed as by name as arguments, and which do not support any convention for requesting that standard input or output be used in place of a file.
The token used by process substitution is platform-dependent; we can see what it is using echo. For instance on GNU/Linux, Bash takes advantage of the /dev/fd operating system feature:
$ echo <(ls -l)
/dev/fd/63
You can use the following command:
strace -T command 2>&1 >/dev/null | awk '{gsub(/[<>]/,"",$NF)}$NF+.0>1.0'
Explanation:
strace -T adds the time spent in the syscall end the end of the line, enclosed in <...>
2>&1 >/dev/null | awk pipes stderr to awk. (strace writes it's output to stderr!)
The awk command removes the <> from the last field $NF and prints lines where the time spent is higher than a second.
Probably you'll also want to pass the threshold as a variable to the awk command:
strace -T command 2>&1 >/dev/null \
| awk -v thres=0.001 '{gsub(/[<>]/,"",$NF)}$NF+.0>thres+.0'
New to bash programming. I am not sure what is meant by 'output to stdout'. Does it mean print out to the command line?
If I have a simple bash script:
#!/bin/bash
wget -q http://192.168.0.1/test -O - | grep -m 1 'Hello'
it outputs a string to the terminal. Does this mean it's 'outputting to stdout' ?
Thanks
Yes, stdout is the terminal (unless it's redirected to a file using the > operator or into the stdin of another process using |)
In your specific example, you're actually redirecting using | grep ... through grep then to the terminal.
Every process on a Linux system (and most others) has at least 3 open file descriptors:
stdin (0)
stdout (1)
stderr (2)
Regualary every of this file descriptors will point to the terminal from where the process was started. Like this:
cat file.txt # all file descriptors are pointing to the terminal where you type the command
However, bash allows to modify this behaviour using input / output redirection:
cat < file.txt # will use file.txt as stdin
cat file.txt > output.txt # redirects stdout to a file (will not appear on terminal anymore)
cat file.txt 2> /dev/null # redirects stderr to /dev/null (will not appear on terminal anymore
The same is happening when you are using the pipe symbol like:
wget -q http://192.168.0.1/test -O - | grep -m 1 'Hello'
What is actually happening is that the stdout of the wget process (the process before the | ) is redirected to the stdin of the grep process. So wget's stdout isn't a terminal anymore while grep's output is the current terminal. If you want to redirect grep's output to a file for example, then use this:
wget -q http://192.168.0.1/test -O - | grep -m 1 'Hello' > output.txt
Unless redirected, standard output is the text terminal which initiated the program.
Here's a wikipedia article: http://en.wikipedia.org/wiki/Standard_streams#Standard_output_.28stdout.29
When I run the time command in shell time ./myapp I get an output like the following:
real 0m0.668s
user 0m0.112s
sys 0m0.028s
However,when I run the command \time -f %e ./myapp I lose precision and I get:
2.01s
Why is the output not with 3 digits of precision as well? If I use the %E command I also lose precision in the same way. How do i change it to have more precision again, but still only have the seconds being outputted?
I based my research in this
Linux / Unix Command: time
You can try /usr/bin/time -p instead. The -p option should display the output in the standard format. Here's an example from my MacBook:
gondolin% /usr/bin/time find . -name '*.pyc' > /dev/null
0.10 real 0.04 user 0.05 sys
gondolin% /usr/bin/time -p find . -name '*.pyc' > /dev/null
real 0.10
user 0.04
sys 0.05
According to die.net, then time utility should allow you to specify the format in the TIME environment variable. The bash builtin does something similar but uses the TIMEFORMAT environment variable instead:
bash-3.2$ time find . -name '*.pyc' > /dev/null
real 0m0.155s
user 0m0.051s
sys 0m0.068s
bash-3.2$ export TIMEFORMAT='real %R
user %U
sys %S'
bash-3.2$ time find . -name '*.pyc' > /dev/null
real 0.107
user 0.049
sys 0.058
bash-3.2$
After asking in other forums, one of them gave me the answer I was looking for. It can be found in here.
I'm running the following command (on Ubuntu)
time wget 'http://localhost:8080/upLoading.jsp' --timeout=0
and get a result in the command line
real 0m0.042s
user 0m0.000s
sys 0m0.000s
I've tried the following:
time -a o.txt wget 'http://localhost:8080/upLoading.jsp' --timeout=0
and get the following error
-a: command not found
I want to get the result to be redirected to some file. How can I do that?
-a is only understood by the time binary (/usr/bin/time), When just using time you're using the bash built-in version which does not process the -a option, and hence tries to run it as a command.
/usr/bin/time -o foo.txt -a wget 'http://localhost:8080/upLoading.jsp' --timeout=0
Checking man time, I guess what you need is
time -o o.txt -a ...
(Note you need both -a and -o).
[EDIT:] If you are in bash, you must also take care to write
/usr/bin/time
(check manpage for explanation)
You can direct the stdout output of any commmand to a file using the > character.
To append the output to a file use >>
Note that unless done explicitly, output to stderr will still go to the console. To direct both stderr and stdout to the same output stream use
command 2>&1 outfile.txt (with bash)
or
command >& outfile.txt (with t/csh)
If you are working with bash All about redirection will give you more details and control about redirection.
\time 2> time.out.text command
\time -o time.out.text command
This answer based on earlier comments. It is tested it works. The advantage of the \ over /usr/bin/ is that you don't have to know the install directory of time.
These answers also only capture the time, not other output.
Exactly the time from GNU writes it's output to stderr and if you want to redirect it to file, you can use --output=PATH parameter of time
See this http://unixhelp.ed.ac.uk/CGI/man-cgi?time
And if you want to redirect stdout to some file, you can use > filename to create file and fill it or >> filename to append to some file after the initial command.
If you want to redirect stderr by yourself, you can use $ command >&2 your_stderr_output
Try to use /usr/bin/time since many shells have their own implementation of time which may or may not support the same flags as /usr/bin/time
so change your command to
/usr/bin/time -a -o foo.txt wget ....
How about your LANG ?
$ time -ao o.txt echo 1
bash: -ao: コマンドが見つかりません
real 0m0.001s
user 0m0.000s
sys 0m0.000s
$ export|grep LANG
declare -x LANG="ja_JP.utf8"
$ LANG=C time -ao o.txt echo 1
1
$ cat o.txt
0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 1984maxresident)k
0inputs+0outputs (0major+158minor)pagefaults 0swaps
Try:
command 2> log.txt
and the real-time output from "command" can be seen in another console window with:
tail -f log.txt
This worked for me:
( time command ) |& tee output.txt
https://unix.stackexchange.com/questions/115980/how-can-i-redirect-time-output-and-command-output-to-the-same-pipe
You can do that with > if you want to redirect the output.
For example:
time wget 'http://localhost:8080/upLoading.jsp' --timeout=0 > output.txt 2>&1
2>&1 says to redirect STDERR to the same file.
This command will erase any output.txt files and creates a new one with your output. If you use >> it will append the output at the end of any existing output.txt file. If it doesn't exist, it will create it.
I'm using Cygwin in a very fast PC but I find it is ridiculously slow when I want to use grep. It also slow when I want to process a large file (say 25Mb). Here I'm using an example to prove my case.
> time for i in $(seq 1000); do grep "$i" .; done
real 75.865 user 5.442 sys 14.542 pcpu 26.34
I want to know
Show me your score. Have you had similar problem with slowness of cygwin or GNU grep
How can you improve the performance
What your tips of using Cygwin
uname -rvs
CYGWIN_NT-6.1-WOW64 1.7.9(0.237/5/3) 2011-03-29 10:10
which grep
grep is /usr/bin/grep
grep is /bin/grep
grep is /usr/bin/grep`
$ time for i in $(seq 1000); do grep "$i" .; done
real 0m13.741s
user 0m3.520s
sys 0m8.577s
$ uname -rvs
CYGWIN_NT-6.1-WOW64 1.7.15(0.260/5/3) 2012-05-09 10:25
$ which grep
/usr/bin/grep