Tonight I tried to write a POSIX shell script which would allow me to check how long a process is running (via it's ID) and be able to handle multiple inputs:
#!/bin/sh
is_this_a_number()
{
if [ "1ドル" -eq "1ドル" ] 2> /dev/null
then
return 0
else
return 1
fi
}
does_pid_exist()
{
if ps --pid "1ドル" > /dev/null 2>&1
then
return 0
else
return 1
fi
}
how_long_pid_has_been_running()
{
ps --pid "1ドル" --format etime=
}
trim_leading_and_trailing_spaces()
{
awk '{1ドル=1ドル;print}'
}
arg_pos=0
while [ "$#" -gt 0 ]
do
arg_val="1ドル"
arg_pos=$((arg_pos + 1))
if ! is_this_a_number "$arg_val"
then
echo "The argument at position $arg_pos is not a number."
else
echo "Process ID $arg_val"
if ! does_pid_exist "$arg_val"
then
echo "This process does not exist."
else
how_long_pid_has_been_running "$arg_val" | trim_leading_and_trailing_spaces
fi
fi
printf "\\n"
shift
done
Usage:
./how-long-pid-is-running 1 10078 c 40545454
Where 10078 is an instance of Chrome.
The output is as follows:
Process ID 1
09:04:31
Process ID 10078
07:32:32
The argument at position 3 is not a number.
Process ID 40545454
This process does not exist.
2 Answers 2
- GNU long options are not POSIX, so instead of
ps --pid "1ドル" --format etime=
, writeps -p "1ドル" -o etime=
. kill -s 0 "1ドル" >/dev/null 2>&1
is much faster thanps --pid "1ドル" > /dev/null 2>&1
, partly becausekill
is a builtin in most shells. Signal 0 is used to test for the existence of a process without sending it a signal.- Consider redirecting the
echo
messages to the appropriate output streams, i.e.stdout
andstderr
. is_this_a_number
,does_pid_exist
: these are used directly inif
clauses, so it'd read more naturally if they are renamed tois_a_number
andpid_exists
.- A minor point here, but I'd reverse the
if
-else
statements to remove the!
negations. Another minor point: during the short time span between testing the existence of a PID and querying the elapsed time since the process with that PID was started, the process with that PID could have finished running or even been substituted with a newly spawned one. You could avoid that by running the second command first, saving the output in a variable and then check for nullness, like thus:
echo "Process ID $arg_val" running_time=$(how_long_pid_has_been_running "$arg_val" 2>/dev/null | trim_leading_and_trailing_spaces) if [ -z "${running_time}" ] then echo "This process does not exist." else echo "${running_time}" fi
- I've seen you write
printf "\\n"
in another post also, so I'm curious: is it any different fromprintf "\n"
? And in any case, anecho
would do the job just as well.
Functions forward the exit status of the last command, so the pattern
f()
{
if $command
then
return 0
else
return 1
fi
}
can be replaced with
f()
{
$command
}
unless you really must force all error returns to 1.