shell.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package shell
  2. import (
  3. "os"
  4. "os/signal"
  5. "regexp"
  6. "strings"
  7. "syscall"
  8. )
  9. func QuoteSplit(s string) []string {
  10. var a []string
  11. for len(s) > 0 {
  12. switch c := s[0]; c {
  13. case '\t', '\n', '\r', ' ': // unicode.IsSpace
  14. s = s[1:]
  15. case '"', '\'': // quote chars
  16. if i := strings.IndexByte(s[1:], c); i > 0 {
  17. a = append(a, s[1:i+1])
  18. s = s[i+2:]
  19. } else {
  20. return nil // error
  21. }
  22. default:
  23. i := strings.IndexAny(s, "\t\n\r ")
  24. if i > 0 {
  25. a = append(a, s[:i])
  26. s = s[i:]
  27. } else {
  28. a = append(a, s)
  29. s = ""
  30. }
  31. }
  32. }
  33. return a
  34. }
  35. // ReplaceEnvVars - support format ${CAMERA_PASSWORD} and ${RTSP_USER:admin}
  36. func ReplaceEnvVars(text string) string {
  37. re := regexp.MustCompile(`\${([^}{]+)}`)
  38. return re.ReplaceAllStringFunc(text, func(match string) string {
  39. key := match[2 : len(match)-1]
  40. var def string
  41. var dok bool
  42. if i := strings.IndexByte(key, ':'); i > 0 {
  43. key, def = key[:i], key[i+1:]
  44. dok = true
  45. }
  46. if value, vok := os.LookupEnv(key); vok {
  47. return value
  48. }
  49. if dok {
  50. return def
  51. }
  52. return match
  53. })
  54. }
  55. func RunUntilSignal() {
  56. sigs := make(chan os.Signal, 1)
  57. signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
  58. println("exit with signal:", (<-sigs).String())
  59. }