Bash-Funk “processes” module
The following commands are available when this module is loaded:
- -get-child-pids
- -get-parent-pid
- -get-toplevel-parent-pid
- -kill-childs
- -kill-listener
- -test-all-processes
License
SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com)
SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-get-child-pids
Usage: -get-child-pids [OPTION]... [PARENT_PID]
Recursively prints all child PIDs of the process with the given PID.
Parameters:
PARENT_PID (default: '$$', integer: 0-?)
The process ID of the parent process. If not specified the PID of the current Bash process is used.
Options:
--printPPID
Specifies to also print the PID of the parent process.
-----------------------------
--help
Prints this help.
--tracecmd
Enables bash debug mode (set -x).
--selftest
Performs a self-test.
--
Terminates the option list.
Implementation:
local childPids # intentional declaration in a separate line, see http://stackoverflow.com/a/42854176
childPids=$(command ps -o pid --no-headers --ppid $_PARENT_PID 2>/dev/null | sed -e 's!\s!!g'; exit ${PIPESTATUS[0]})
if [[ $? != 0 ]]; then
echo "No process with PID ${1} found"'!'
return 1
fi
for childPid in $childPids; do
-get-child-pids --printPPID $childPid
done
if [[ $_printPPID ]]; then
echo $_PARENT_PID
fi
-get-parent-pid
Usage: -get-parent-pid [OPTION]... [CHILD_PID]
Prints the PID of the parent process of the child process with the given PID.
Parameters:
CHILD_PID (default: '$$', integer: 0-?)
The process ID of the child process. If not specified the PID of the current Bash process is used.
Options:
--help
Prints this help.
--tracecmd
Enables bash debug mode (set -x).
--selftest
Performs a self-test.
--
Terminates the option list.
Implementation:
local parentPid # intentional declaration in a separate line, see http://stackoverflow.com/a/42854176
parentPid=$(cat /proc/${_CHILD_PID}/stat 2>/dev/null | awk '{print $4}'; exit ${PIPESTATUS[0]})
if [[ $? != 0 ]]; then
echo "No process with PID ${_CHILD_PID} found"'!'
return 1
fi
echo $parentPid
-get-toplevel-parent-pid
Usage: -get-toplevel-parent-pid [OPTION]... [CHILD_PID]
Prints the PID of the top-level parent process of the child process with the given PID.
Parameters:
CHILD_PID (default: '$$', integer: 0-?)
The process ID of the child process. If not specified the PID of the current Bash process is used.
Options:
--help
Prints this help.
--tracecmd
Enables bash debug mode (set -x).
--selftest
Performs a self-test.
--
Terminates the option list.
Implementation:
local pid=$_CHILD_PID
while [[ $pid != 0 ]]; do
pid=$(-get-parent-pid ${pid})
if [[ $? != 0 ]]; then
echo $pid
return 1
fi
done
echo ${pid}
-kill-childs
Usage: -kill-childs [OPTION]... [PARENT_PID]
Sends the TERM(15) signal to all child processes of the process with the given PID.
Parameters:
PARENT_PID (default: '$$', integer: 0-?)
The process ID of the parent process. If not specified the PID of the current bash process is used.
Options:
-s, --signal VALUE (integer: 1-64)
The signal to be send, eg. 9=KILL or 15=TERM.
-----------------------------
--help
Prints this help.
--tracecmd
Enables bash debug mode (set -x).
--selftest
Performs a self-test.
--
Terminates the option list.
Implementation:
local signal=${_signal:-15}
local childPids # intentional declaration in a separate line, see http://stackoverflow.com/a/42854176
childPids=$(-get-child-pids $_PARENT_PID)
if [[ $? != 0 ]]; then
echo $childPids
return 1
fi
for childPid in $childPids; do
echo "Killing process with PID $childPid..."
kill -s $signal $childPid 2> /dev/null || :
done
-kill-listener
Usage: -kill-listener [OPTION]... PORT
Sends the given kill signal the process listening on the given TCP port.
Requirements:
+ Command 'netstat' must be available.
Parameters:
PORT (required, integer: 0-65535)
TCP Port number to check.
Options:
-s, --signal VALUE (integer: 1-64)
The signal to be send, eg. 9=KILL or 15=TERM.
-----------------------------
--help
Prints this help.
--tracecmd
Enables bash debug mode (set -x).
--selftest
Performs a self-test.
--
Terminates the option list.
Implementation:
local signal=${_signal:-15}
if hash netstat &>/dev/null; then
local listener=$(netstat -lantp 2>/dev/null | sed -En "s/^tcp\s+[0-9]+\s+[0-9]+ .*:$_PORT .* (-|[0-9]+\/[^ ]*)\s+$/\1/p" | uniq || :)
if [[ $listener == "-" ]]; then
echo "-kill-listener: Could not determine PID of processs listening on TCP port $_PORT. Try using sudo."
return 1
else
echo "-kill-listener: No listening process on TCP port $_PORT found."
return 0
fi
else
local listener=$(lsof -iTCP:$_PORT | sed -En "s/([^ ]+)\s+([0-9]+).*\s+/\2\/\1/p" | uniq || :)
if [[ ! $listener ]]; then
if [[ $EUID -eq 0 ]]; then
echo "-kill-listener: No listening process on TCP port $_PORT found."
return 1
else
echo "-kill-listener: Could not determine if a processs is listening on TCP port $_PORT. Try using sudo."
return 1
fi
fi
fi
if [[ $listener ]]; then
local pid=${listener%%/*}
echo "-kill-listener: Sending kill signal $signal to process $process..."
kill -$signal $pid
return
fi
-test-all-processes
Usage: -test-all-processes [OPTION]...
Performs a selftest of all functions of this module by executing each function with option '--selftest'.
Options:
--help
Prints this help.
--tracecmd
Enables bash debug mode (set -x).
--selftest
Performs a self-test.
--
Terminates the option list.
Implementation:
-get-child-pids --selftest && echo || return 1
-get-parent-pid --selftest && echo || return 1
-get-toplevel-parent-pid --selftest && echo || return 1
-kill-childs --selftest && echo || return 1
-kill-listener --selftest && echo || return 1