Co-worker on another project wanted to know "how do I write a script to restart a process only if it was last started before the system was most-recently patched. So, I Slacked him a quick "one-liner" of:
if [[ $( date -d "$( ps -p $( pgrep <SERVICE_PROCESS_NAME> ) -o lstart= )" "+%s" ) -lt $( rpm -qa --qf '%{installtime}\n' | sort -n | tail -1 ) ]] then <CODE_TO_EXECUTE> … else echo "Nothing to do (service restarted since last RPM was installed)" fi
The above is a simple equality test where two (epoch) times are being compared. Epoch-time is used for comparison as it is the easiest format from which to determine, "is Time-1 more or less recent than Time-2".
Left-hand comparator:
The left expression uses a nested subshell to convert the target-processes start time from its normal format to epoch time. From the inside of the nest outward:
- Use `pgrep` to get the process-ID (PID) of the target service. The <SERVICE_PROCESS_NAME> value needs to be a string that appears only once in the process table
- Use the `ps` utility's `-p` flag to constrain output to that of the PID returned from the `pgrep` subshell and display only the targeted-process's `lstart` attribute. The `lstart` attribute is one of several start-related attributes for a process (see man page for details). Use of `lstart` attribute is because it provides a full time-specification. The other start-related attributes provide shorter, less-complete time-specifications that are not suitable for conversion to epoch time.
- Use the `date` utility's `-d` flag to specify the format of the time-string returned by the `ps` subshell – converting that subshell's time-string to epoch-format with the `%s` format-specifier.
Right-hand comparator:
The right expression is getting the install time of the most recently installed RPM. When using the `rpm` utility's query-format (`--qf`) to dump out an RPM's `installtime` attribute, the attribute-string is already in epoch-format and requires no further output-massaging. When using the `rpm` utility's "query all" capability, output is not time-sorted. Since the `installtime` attribute is just a numerical string, the output can be effectively time-sorted by using `sort -n`. Since we're only interested in the youngest RPM, using `tail -1` gets us the final element of the number-sorted output.
I did note to my co-worker that, if they're following a "patch and reboot" standard that his service-process should never be older than the most-recently installed RPM. So, not sure what the ultimate aim of the test will be.
No comments:
Post a Comment