2
\$\begingroup\$

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.
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Dec 13, 2017 at 20:06
\$\endgroup\$

2 Answers 2

2
\$\begingroup\$
  • GNU long options are not POSIX, so instead of ps --pid "1ドル" --format etime=, write ps -p "1ドル" -o etime=.
  • kill -s 0 "1ドル" >/dev/null 2>&1 is much faster than ps --pid "1ドル" > /dev/null 2>&1, partly because kill 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 and stderr.
  • is_this_a_number, does_pid_exist: these are used directly in if clauses, so it'd read more naturally if they are renamed to is_a_number and pid_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 from printf "\n"? And in any case, an echo would do the job just as well.
answered Dec 18, 2017 at 19:14
\$\endgroup\$
0
1
\$\begingroup\$

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.

answered Dec 18, 2017 at 19:37
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.