functions.sh 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #!/bin/sh
  2. # useful functions
  3. # 2013-09-26 11:00 created by niujiuru
  4. # 2026-01-05 13:40 updated by niujiuru
  5. # export envionment variables
  6. export_env()
  7. {
  8. PATH="/bin:/sbin:/usr/bin:/usr/sbin"
  9. CWD=$(cd "$(dirname "$0")" && pwd) || exit 1
  10. export PATH CWD
  11. }
  12. # load module by name
  13. # pass THIS_MODULE to module
  14. # $1: module name (no path, no '..')
  15. load_module()
  16. {
  17. local module="$1"
  18. [ -n "$module" ] || return 1
  19. case "$module" in
  20. */*|*..*) return 1 ;;
  21. esac
  22. THIS_MODULE="${module}"
  23. [ -f "${CWD}/modules/${module}" ] || return 1
  24. . "${CWD}/modules/${module}"
  25. }
  26. # load module & call module's method
  27. # $1: module name
  28. # $2: method name (function defined in module)
  29. # $...: method params
  30. call_module()
  31. {
  32. [ $# -ge 2 ] || return 1
  33. local module="$1"
  34. local method="$2"
  35. shift 2
  36. load_module "$module" || return 1
  37. type "$method" >/dev/null 2>&1 || return 1
  38. "$method" "$@"
  39. return $?
  40. }
  41. # check if the program is currently running
  42. # $1: program's executable path
  43. # return 0 if running, 1 otherwise
  44. is_running()
  45. {
  46. local target="$1" pid exe
  47. [ -n "$target" ] || return 1
  48. for pid in /proc/[0-9]*; do
  49. [ -r "$pid/exe" ] || continue
  50. exe=$(readlink "$pid/exe" 2>/dev/null) || continue
  51. [ "$exe" = "$target" ] && return 0
  52. done
  53. return 1
  54. }
  55. # kill program(s) by name
  56. # $1: program's executable path
  57. # $2: signal to send (default: 15)
  58. kill_programs()
  59. {
  60. local target="$1" pid exe
  61. local sig=${2:-15}
  62. [ -n "$target" ] || return 1
  63. case "$sig" in
  64. ''|*[!0-9]*) return 1 ;;
  65. esac
  66. [ "$sig" -ge 1 -a "$sig" -le 64 ] 2>/dev/null || return 1
  67. for pid in /proc/[0-9]*; do
  68. [ -r "$pid/exe" ] || continue
  69. exe=$(readlink "$pid/exe" 2>/dev/null) || continue
  70. if [ "$exe" = "$target" ]; then
  71. kill -$sig "${pid##*/}" 2>/dev/null
  72. fi
  73. done
  74. }
  75. # gracefully terminate program by executable path
  76. # send SIGTERM and wait, then SIGKILL if timeout
  77. # $1: program's executable path
  78. # $2: timeout in seconds (default: 5)
  79. # return 0 if terminated gracefully
  80. # return 2 if force killed after timeout
  81. graceful_kill() {
  82. local target="$1" timeout="${2:-5}" waited=0
  83. [ -n "$target" ] || return 1
  84. kill_programs "$target" 15 || return 1
  85. while is_running "$target" && [ "$waited" -lt "$timeout" ]; do
  86. sleep 1
  87. waited=$((waited + 1))
  88. done
  89. if is_running "$target"; then
  90. kill_programs "$target" 9
  91. return 2
  92. fi
  93. return 0
  94. }