1#!/usr/bin/env python3

2

3 import os

4 import sys

5 import time

6

7 from optparse import OptionParser

8 from subprocess import Popen, PIPE

9

10

11 COMMAND_FORMAT = "pgrep -f %(options)s %(process)s"

12

13

14 def process_pids(process, *options):

15 options_string = " ".join(options)

16 command = COMMAND_FORMAT % {"options": options_string, "process": process}

17

18 # Exclude this process and the pgrep process

19 subprocess = Popen(

20 command, stdout=PIPE, shell=True, universal_newlines=True

21 )

22 exclude_pids = [os.getpid(), os.getppid(), subprocess.pid]

23

24 pids_string = subprocess.communicate()[0]

25 pids = [int(pid) for pid in pids_string.split()]

26

27 result = set(pids).difference(exclude_pids)

28 return list(result)

29

30

31 def process_count(*args):

32 return len(process_pids(*args))

33

34

35 def main(args):

36 default_sleep = 1

37

38 usage = "Usage: %prog PROCESS [PROCESS...]"

39 parser = OptionParser(usage=usage)

40 parser.add_option(

41 "-s",

42 "--sleep",

43 type="int",

44 default=default_sleep,

45 help="Number of seconds to sleep between checks.",

46 )

47 parser.add_option(

48 "-t",

49 "--timeout",

50 type="int",

51 help="Number of seconds to timeout from sleeping.",

52 )

53 parser.add_option(

54 "-u",

55 "--uid",

56 help="Effective user name or id of the running processes",

57 )

58 (options, processes) = parser.parse_args(args)

59

60 process_args = []

61 if options.uid is not None:

62 process_args.extend(["-u", options.uid])

63

64 while True:

65 for process in processes:

66 if process_count(process, *process_args):

67 break

68 else:

69 break

70

71 if options.timeout is not None:

72 if options.timeout <= 0:

73 return 1

74 else:

75 options.timeout -= options.sleep

76

77 time.sleep(options.sleep)

78

79 return 0

80

81

82 if __name__ == "__main__":

83 sys.exit(main(sys.argv[1:]))