How to get time in seconds since process started, without using etimes? - linux

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

Related

How to run a scrip if the time is matched with a time in another time zones

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)

How to get time since file was last modified in seconds with bash?

I need to get the time in seconds since a file was last modified. ls -l doesn't show it.
There is no simple command to get the time in seconds since a file was modified, but you can compute it from two pieces:
date +%s: the current time in seconds since the Epoch
date -r path/to/file +%s: the last modification time of the specified file in seconds since the Epoch
Use these values, you can apply simple Bash arithmetic:
lastModificationSeconds=$(date -r path/to/file +%s)
currentSeconds=$(date +%s)
((elapsedSeconds = currentSeconds - lastModificationSeconds))
You could also compute and print the elapsed seconds directly without temporary variables:
echo $(($(date +%s) - $(date -r path/to/file +%s)))
In BASH, use this for seconds since last modified:
expr `date +%s` - `stat -c %Y /home/user/my_file`
I know the tag is Linux, but the stat -c syntax doesn't work for me on OSX. This does work...
echo $(( $(date +%s) - $(stat -f%c myfile.txt) ))
And as a function to be called with the file name:
lastmod(){
echo "Last modified" $(( $(date +%s) - $(stat -f%c "$1") )) "seconds ago"
}

Grep time command output

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

Increase %e precision with /usr/bin/time shell command (Linux)

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.

Better quote to execute command on shell script

I'm in doubt of the diference and which one is the better quote to execute a command in shell script.
For example, I have this two examples:
echo "The name of the computer is `uname -n`"
echo "The name of the computer is $(uname -n)"
Which one is better? Or there is no diference?
The $(...) one is generally recommended because it nests easier. Compare:
date -d "1970-01-01 $(echo "$(date +%s)-3600"|bc) sec UTC"
date -d "1970-01-01 `echo \"\`date +%s\`-3600\"|bc` sec UTC "

Resources