Python进程监控问题:subprocess PID判断失效及psutil替代方案咨询
Let's tackle your two main problems one at a time—first fixing the subprocess/pgrep bug, then switching to a more robust psutil solution that handles your Java app scenario.
1. Fixing the subprocess/pgrep Logic Error
It sounds like you hit a super common Python gotcha: you were checking the function object itself instead of calling the function and evaluating its return value. For example, if your loop looked like this:
import subprocess def check_essentials(process_name): result = subprocess.run(['pgrep', '-f', process_name], capture_output=True, text=True) return result.returncode == 0 # Wrong approach (checks if the function exists, not its output) process_list = ["my-service", "another-service"] for proc in process_list: if check_essentials: print(f"{proc} is running") else: print(f"{proc} is missing!")
That’s why it always hit the else branch—check_essentials is a function object, which is always "truthy" in Python, but you never passed the process name or checked what the function actually returns. The fix is simple: call the function with the process name argument and check its boolean result:
# Correct approach for proc in process_list: if check_essentials(proc): print(f"{proc} is running") else: print(f"{proc} is missing!")
This will properly evaluate whether pgrep -f found the target process.
2. Using psutil to Simulate pgrep -f for Java Apps
You’re right that psutil is a better fit for process monitoring—it’s more Pythonic, avoids shell dependencies, and gives you deeper process insights. The trick with Java apps is that the name() attribute only returns "java", but the full command line (including the jar file or main class you’re targeting) lives in the cmdline() property.
Here’s a function that mimics pgrep -f by checking if your target string exists anywhere in the process’s full command line:
import psutil def check_process_running(target_str): for proc in psutil.process_iter(['pid', 'cmdline']): try: # Join the command line arguments into a single string (matches pgrep -f behavior) full_cmd = ' '.join(proc.info['cmdline']) if target_str in full_cmd: return True except (psutil.NoSuchProcess, psutil.AccessDenied): # Skip processes that exit mid-check or that we don't have permission to inspect continue return False
How this works:
psutil.process_iter(['pid', 'cmdline'])iterates over all running processes, fetching only the PID and command line (to save resources).- We join the
cmdlinelist (split into individual arguments) into a single string, just likepgrep -fmatches against the full command line. - We check if your target string (e.g., "user-auth-service.jar" or "com.mycompany.ApiGateway") is present in that full command line.
- We handle common exceptions for processes that exit mid-check or that we don’t have permission to access.
You can use this in your loop just like before:
java_services = ["user-auth-service.jar", "api-gateway.jar"] for service in java_services: if check_process_running(service): print(f"✅ {service} is running") else: print(f"❌ ALERT: {service} is not running!")
This will correctly identify your specific Java services even though their process name is just "java".
内容的提问来源于stack exchange,提问作者SVill

