2
\$\begingroup\$

In this code I find a list all of the running java processes and give the below function a name to look for, it will do its best. But since I find my approach a little too ugly, could some POSIX shell script writer have a look and possibly give me some simplification recommendations?


#!/bin/sh

# here is an ugly constant vuze java process name
readonly vuze_java_process_name='org.gudy.azureus2.ui.swt.Main'

is_java_program_running()
# expected arguments:
# $1 = java program name
{
    # there will always be at least one java process:
    # jdk.jcmd/sun.tools.jps.Jps, which is actually
    # the program giving us the list of java processes
    java_process_list=$( jps -l | awk '{print $2}' )

    # this behaves strangely if there is zero processes (needs verification)
    # but since there is always at least one, no problem here
    java_process_list_count=$(( $( printf '%s\n' "${java_process_list}" | wc -l ) ))

    # set the result value as if we did not find it
    result=false

    # POSIX-ly simulate FOR loop
    i=1; while [ "${i}" -le "${java_process_list_count}" ]
    do
        # here we take one line from the list on $i position
        java_process_entry=$( echo "${java_process_list}" | sed --posix --quiet "${i}{p;q}" )
        # compare the given process entry with given java program name
        if [ "${java_process_entry}" = "${1}" ]
        then
            # set the result value
            result=true
            # end this loop
            break
        fi
        # increase iterator
        i=$(( i + 1 ))
    done

    # depending on if we found vuze process running,
    # return positive or negative result value
    if [ "${result}" = true ]
    then
        return 0
    else
        return 1
    fi
}

###
### EXAMPLE on Vuze
###

# keep Vuze alive forever, check in 5 seconds interval
while true
do
    sleep 5s

    if ! is_java_program_running "${vuze_java_process_name}"
    then
        my_date_time=$(date +%Y-%m-%d_%H:%M:%S)
        printf '%s  %s\n' "${my_date_time}" "(re-)starting Vuze"
        ( /home/vlastimil/Downloads/vuze/vuze > /dev/null 2>&1 & )
    fi
done
\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

Instead of simulating a for (( expr1 ; expr2 ; expr3 )) loop, use a POSIX

    for java_process_entry in $java_process_list

Notice that now you don't need to compute the number of lines, neither invoke sed.


There is noting wrong with early return. return 0 as soon as the desired process is found.


There is no need to store the entire list in a variable, neither invoke awk. Process the jps output sequentially.

All that said, consider

    is_java_program_running()
    {
        jps -l | while read pid java_process_entry; do
            if [ $java_process_entry = "${1}" ]; then return 0; fi
        done
        return 1
    }
\$\endgroup\$
1
\$\begingroup\$

(On top of what @vnp already wrote.)


When these lines are the last in a function:

if [ "${result}" = true ]
then
    return 0
else
    return 1
fi

Then you can write simply:

[ "${result}" = true ]

Because the exit code of a function is the exit code of its last executed statement.

\$\endgroup\$
1
  • \$\begingroup\$ In fact, given that the only other possible value of $result is false, we can just expand and execute it. \$\endgroup\$ Commented Feb 25, 2019 at 19:06

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.