Is there any commands/parameters, which allow me to know for how long the process has been working? I tried to search something in commands ps and top , but didn't find it.
For a process whose time you want to (or accept to) collect after it ends, simply use the time command. It's available as an independent command and usually as a shell builtin as well.
$ time sleep 5
real 0m5.028s
user 0m0.000s
sys 0m0.000s
For a process that's still running, have a look at ps's formatting options.
$ ps -o time,etime 1
Exact option name might vary with the system, be sure to check your ps manual.
Related
I would like to use AppleScript to batch run a bunch of programs and get the time that each one ran.
Example: From the command line I would type time ls like this:
$ time ls
Applications
bin
net
Library
... etc
real 0m0.013s
user 0m0.002s
sys 0m0.006s
but when I try to use apple script and put the results into a variable, it completely ignores the time output.
Example:
set result to do shell script "time ls"
returns
Applications
bin
net
Library
... etc
with no mention of the time execution time anywhere.
Even making this more simple:
set result to do shell script "time"
returns
""
How do I get the time of execution back from AppleScript?
p.s. I'm not actually trying to time ls. I want to time a bunch of custom created programs, but ls makes simple example.
Use the exec 2>&1 command to redirect the STDERR to STDOUT, like this:
do shell script "exec 2>&1; time ls"
I need to create some sort of fail safe in one of my scripts, to prevent it from being re-executed immediately after failure. Typically when a script fails, our support team reruns the script using a 3rd party tool. Which is usually ok, but it should not happen for this particular script.
I was going to echo out a time-stamp into the log, and then make a condition to see if the current time-stamp is at least 2 hrs greater than the one in the log. If so, the script will exit itself. I'm sure this idea will work. However, this got me curious to see if there is a way to pull in the last run time of the script from the system itself? Or if there is an alternate method of preventing the script from being immediately rerun.
It's a SunOS Unix system, using the Ksh Shell.
Just do it, as you proposed, save the date >some file and check it at the script start. You can:
check the last line (as an date string itself)
or the last modification time of the file (e.g. when the last date command modified the somefile
Other common method is create one specified lock-file, or pid-file such /var/run/script.pid, Its content is usually the PID (and hostname, if needed) of the process what created it. Of course, the file-modification time tell you when it is created, by its content you can check the running PID. If the PID doesn't exists, (e.g. pre process is died) and the file modification time is older as X minutes, you can start the script again.
This method is good mainly because you can use simply the cron + some script_starter.sh what will periodically check the script running status and restart it when needed.
If you want use system resources (and have root access) you can use the accton + lastcomm.
I don't know SunOS but probably knows those programs. The accton starts the system-wide accounting of all programs, (needs to be root) and the lastcomm command_name | tail -n 1 shows when the command_name is executed last time.
Check the man lastcomm for the command line switches.
So, I need to run a program, not keep track of its PID (in memory, at least), and later kill that program. Any ideas? My immediate thought was to tag the process with something I could find later, but that seems a bust. My next thought was to store on disk the PID, but I've no idea what the convention for that sort of thing is. Any ideas? Thanks!
Your program can create a directory under /var/run/ to store such files. For instance, if your program is myprog it might store its PID on startup in
/var/run/myprog/PID
If your program could have multiple instances running at the same time, you might use the PID itself in the file name, along with its startup time, to ensure a unique file name for each instance.
/var/run/myprog/201410302306.1283.pid
(Note that if you use the PID in the file name, it's up to you if you actually write the PID in the file itself; an empty file would suffice.)
The most straight forward (and common case) is, as you and chepner already mentioned, to store it in a pid file. For this:
If it's a system wide programm:
/var/run/prog.pid
If it's a system installed program that might be run multiple times:
/var/run/prog/prog_instance.pid
If it's a user local program:
$HOME/.prog/prog.pid
Other options might be to use pgrep for finding it as long as you can uniquely define the calling command. For example pass a dummy argument not used and use it for retrieval:
$ prog.sg --instance_1234 &
$ pgrep -f -- '--instance_1234'
3523
you can use start-stop-daemon to start a program and kill it later. It has a lot of options to find the programm, the most usefull is the --pid that stores and retrive the pid from a file in filesystem, usually in /var/run (pay attention to file system privileges to write in it).
See the man pages for more tips.
How do you extend the output of ps -fe in Solaris so that it displays more than 80 characters? My process has several arguments and the process name could not be displayed anymore.
You can't display them with the default ps (/usr/bin/ps) which is a SVR4 regular one.
To get the full argument line, use the BSD ps (UCB = University of California at Berkeley):
/usr/ucb/ps -alxwww
We have finally fixed this in Solaris; as of Solaris 11.3 SRU 5, all original argument vectors as well as the environment variables can be retrieved from /proc. ps will now print all of the command line.
Fixed in Solaris 11.3 SRU 5
The simple answer is that there is no way to reliably acquire the full arguments to processes on Solaris for processes owned by other users. If you have root or other privileged access you can use /usr/ucb/ps on older versions, and 'pargs' or similar tools on newer versions (there is no tool which works across all versions).
Essentially Solaris stores the original args at process start time, while most other platforms allow ps to access, via some means, the contents of argv at runtime for the process. This stored-copy is in a special kernel data structure with limited (80 byte) size. This also means that it's not possible for a program to modify the args post-start as displayed by ps for useful or nefarious means.
Thus, if you need to access the command line for portable purposes, such as pid checking, you will need to choose between enforcing a short command line via hacks like launching programs controlled execp paths without absolute paths, or you will need to forgo that portable functionality on Solaris.
you can use pargs PID
it will give you more information than ps
Try ps -efl. If that doesn't work (I don't have a Solaris box handy) you can also try ps -efl | cat (as some programs check whether they're outputting to a terminal to decide on their output width).
There are two sets of options available for ps. Others will chime in with the correct names ( ( maybe BSD and SRVn)?)
With the non-options-preceded-with-a-hyphen-version, you can do
ps auxww(w?) | grep ${PID} to extend the length of the command detail that is printed (again, notice NO leading '-' option indicator).
Note that in some cases you will see a lot of environment variable assignments before the actually command, i.e. myPath=... cfgFile=... /path/to/command ... args ...
I think that 'www' in some systems will print everything, regardless how long the command is.
Finally, in my experience using ps to do a lot of crazy things, I would ocassionally have a PID and the output would display the first 6? columns, but the space reserved for the command was empty or had some sort of place holder value. I eventually found out why that was true, by searching comp.unix.shell, but it's too long ago now to be sure and I don't have access to Solaris systems right now.
I hope this helps.
I tried using t1=$(date +%s%N) to get the time in nanoseconds, but I kept in getting this error:
./script.sh: line 10: 1292460931N: value too great for base (error token is "1292460931N")
I looked up online and it seems that you can use the "time" command, however I can't find a good example of using the time command. Any help would be appreciated :)
The date command you're using doesn't support %N so your output is literally 1292460931N. I tried it on Linux and it worked, but on FreeBSD I see the results you got. Run that date command in a shell and see what comes out. Is it possible you're using busybox? Its cut-down date command also omits %N but the version I just tried gave me 1292463535%N.
Okay, a couple of things here.
First, not a lot of systems can give you a time that actually accurate to nanoseconds anyway.
Now, using time, either as /usr/bin/time or the shell builtin (bash: help time) is very easy. If the command you want to time is foo1, then
$ time foo
will return the elapsed time as three lines on stderr
real 0m0.001s
user 0m0.000s
sys 0m0.000s
which you can use any way you like.
If you want to get a better, more accurate timing, execute the command many times. This can be as simple as writing a short loop
time for i in 0 1 2 3 4; do foo; done
will do foo five times and give you the total time. You probably want to do more than 5 iterations, so you'd probably want a counter and a while loop or the like.