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.
Related
Currently, I am using cloud VMs to run my code and because of that I am assigned with a new VM that is in a different time zone. I want to run a bash script that runs a python script at 7:30 pm (Eastern time). From here I know how to run a bash script at a specific time, e.g., echo "ls -l" | at 07:00. From here I know how to get the current time of Eastern time, e.g., TZ=America/New_York date. Also, from here I know how to get only the time using date +%R.
I am a Python coder and tried my best to write a sudo code that shows what I am trying to accomplish as a bash script:
while true
do
Now=TZ=America/New_York date +%R
if [Now -eq 7:30pm]
then
python3 myfile.py
done
As you already know how to set the at command to execute a command
at the specified time, and how to convert the EST to the local time,
you can just combine them:
echo "python3 myfile.py" | at $(date -d "19:30 EST" +%R)
When you invoke the at command, it always warns
"commands will be executed using /bin/sh". It will matter only if we invoke
a bash specific command such as:
echo "shopt -s globstar; ls **" | at ..
which will fail.
In our case, the command python3 myfile.py will run with both
/bin/sh and /bin/bash then you do not worry about the warning.
date -d STRING interprets the STRING as a date/time representation
and prints the converted date/time in the specified format +%R.
If you want to send the output to a file, you can say:
echo "python3 myfile.py > /path/to/a/file" | at $(date -d "19:30 EST" +%R)
In order to output to the current terminal, first identify the terminal
with tty command:
$ tty
=> /dev/pts/0
Then redirect the output to the terminal with:
echo "python3 myfile.py > /dev/pts/0" | at $(date -d "19:30 EST" +%R)
Trying to use ps to find the number of seconds since a process started. The version of ps I have doesn't support etimes and not sure how else to get this info?
For process of pid 1234, you could use the mtime field of meta-data of pseudo-file /proc/1234/status. Read proc(5) for more.
See also stat(2) and stat(1) and date(1).
So date +%s is giving the current date since the Unix epoch, e.g. 1479125355 now in November 14th, 2016. stat -c %Y /proc/1234/status is giving the start time of process 1234 since Unix epoch. You want the difference. Perhaps use (barely tested, my interactive shell is zsh) $[$(date +%s) - $(stat -c %Y /proc/1234/status)]; adapt that to your shell.
For example:
bash -c 'sleep 4; echo $(($(date +%s) - $(stat -c %Y /proc/$$/status)))'
is giving me 4 as expected. Of course the $$ is expanded to the pid of the bash -c command
I would like to randomly select one random command in a bash script.
I have tried commands like
echo $(( $RANDOM % 12 ))
But they work in the UNIX command line but not in my bash script.
Anyone have a solution for my problem?
-- Updated answer as per discussion in comments --
For Bash Users:
Code given in question works fine. Just don't forget to set permissions to +x (grants executable permission to all). Eg: chmod +x myscript.sh
Caution: Don't set RANDOM to a value. It looses its special properties.
Bash man page says-
RANDOM Each time this parameter is referenced, a random integer
between 0 and 32767 is generated. The sequence of random numbers may
be initialized by assigning a value to RANDOM. If RANDOM is unset, it
loses its special properties, even if it is sub- sequently reset.
For dash Users:
sh in ubuntu is a symbolic link to dash.
dash does not support RANDOM variable, it is just another variable.
If you are bound to use sh, you can use date function to generate
pseudo randoms only if your script is not time-dependent. (if your
script runs at strict intervals of time, it might produce same values)
RANDOM=`date '+%s'`
echo $(( $RANDOM % 12 )) # To generate random numbers less than 12
In General:
If you want to generate true random numbers use this-
dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -f1 -d" "
Source: http://www.linuxquestions.org/questions/programming-9/shell-script-random-variable-4088/
Create the shell script test.sh
chmod +x test.sh
content of test.sh
#!/bin/bash
echo $(( $RANDOM % 12 ))
Run it via
bash test.sh
or
./test.sh
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
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.