functions.sh 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. exe=$(readlink "$pid/exe" 2>/dev/null) || continue
  50. exe="${exe% *}"
  51. [ "$exe" = "$target" ] && return 0
  52. done
  53. return 1
  54. }
  55. # kill program(s) by path
  56. # $1: program's executable path
  57. # $2: signal to send (default: 15)
  58. kill_by_path()
  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. exe=$(readlink "$pid/exe" 2>/dev/null) || continue
  69. exe="${exe% *}"
  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 1 function failed
  81. # return 2 if force killed after timeout
  82. graceful_kill() {
  83. local target="$1" timeout="${2:-5}" waited=0
  84. [ -n "$target" ] || return 1
  85. kill_by_path "$target" 15 || return 1
  86. while is_running "$target" && [ "$waited" -lt "$timeout" ]; do
  87. sleep 1
  88. waited=$((waited + 1))
  89. done
  90. if is_running "$target"; then
  91. kill_by_path "$target" 9
  92. return 2
  93. fi
  94. return 0
  95. }