Last active
March 28, 2025 19:34
-
-
Save JKc66/2ecc291f7f494d1cdf6f6479cfa0a86c to your computer and use it in GitHub Desktop.
to view python scripts running by user ubuntu
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
ps aux | grep -E '[p]ython|[p]ython3' | grep "^ubuntu" | grep -v 'networkd-dispatcher\|unattended-upgrade\|vscode-server\|mypython_script' | awk ' | |
BEGIN { | |
BOLD="\033[1m" | |
YELLOW="\033[33m" | |
GREEN="\033[32m" | |
BLUE="\033[34m" | |
MAGENTA="\033[35m" | |
CYAN="\033[36m" | |
WHITE="\033[37m" | |
RED="\033[31m" | |
RESET="\033[0m" | |
user_width = 8 | |
pid_width = 6 | |
cpu_width = 4 | |
mem_width = 4 | |
status_width = 10 | |
cmd_width = 36 | |
} | |
{ | |
if (length($1) > user_width) user_width = length($1) | |
if (length($2) > pid_width) pid_width = length($2) | |
command = "" | |
for (i=11; i<=NF; i++) command = command " " $i | |
command = substr(command, 2) | |
# Extract the Python script path | |
script_path = "" | |
split(command, cmd_parts, " ") | |
for (i in cmd_parts) { | |
if (cmd_parts[i] ~ /\.py$/) { | |
script_path = cmd_parts[i] | |
break | |
} | |
} | |
if (script_path == "") { | |
script_path = command | |
} else { | |
# Get working directory of the process | |
cmd = "pwdx " $2 " 2>/dev/null | cut -d: -f2-" | |
cmd | getline pwd | |
close(cmd) | |
pwd = substr(pwd, 2) # Remove leading space | |
# Combine pwd and script_path | |
if (script_path ~ /^\//) { | |
# If script_path is absolute, use it as is | |
full_path = script_path | |
} else { | |
# If script_path is relative, combine with pwd | |
full_path = pwd "/" script_path | |
} | |
# Remove /home/ubuntu/ prefix if present | |
sub(/^\/home\/ubuntu\//, "", full_path) | |
# Extract up to three directory levels and the filename | |
split(full_path, path_parts, "/") | |
if (length(path_parts) > 3) { | |
script_path = path_parts[length(path_parts)-2] "/" path_parts[length(path_parts)-1] "/" path_parts[length(path_parts)] | |
} else { | |
script_path = full_path | |
} | |
} | |
# Get process start time for uptime calculation | |
cmd = "ps -o etimes= -p " $2 | |
cmd | getline process_uptime | |
close(cmd) | |
# Calculate uptime string | |
uptime_str = "Up " get_uptime_str(process_uptime) | |
if (length(uptime_str) > status_width) status_width = length(uptime_str) | |
# Store command length for dynamic sizing | |
if (length(script_path) > cmd_width) cmd_width = length(script_path) | |
pid_array[$2] = sprintf("%s|%s|%s|%s|%s|%s", $1, $2, $3, $4, uptime_str, script_path) | |
} | |
END { | |
if (length(pid_array) == 0) { | |
printf "No Python processes found for user ubuntu.\n" | |
exit 0 | |
} | |
# Get terminal width for dynamic sizing | |
cmd = "tput cols" | |
cmd | getline term_width | |
close(cmd) | |
# Calculate available space and adjust column widths | |
fixed_width = user_width + pid_width + cpu_width + mem_width + status_width + 13 | |
available_cmd_width = term_width - fixed_width | |
if (available_cmd_width < 20) available_cmd_width = 20 | |
if (available_cmd_width < cmd_width) cmd_width = available_cmd_width | |
border = sprintf("┌%s┬%s┬%s┬%s┬%s┬%s┐", rep("─", user_width), rep("─", pid_width), rep("─", cpu_width), rep("─", mem_width), rep("─", status_width), rep("─", cmd_width)) | |
printf "%s\n", border | |
header = sprintf("│%s%-*s%s│%-*s│%4s│%4s│%-*s│%-*s│", BOLD, user_width, "USER", RESET, pid_width, "PID", "CPU", "MEM", status_width, "STATUS", cmd_width, "COMMAND") | |
printf "%s\n", header | |
middle = sprintf("├%s┼%s┼%s┼%s┼%s┼%s┤", rep("─", user_width), rep("─", pid_width), rep("─", cpu_width), rep("─", mem_width), rep("─", status_width), rep("─", cmd_width)) | |
printf "%s\n", middle | |
n = asorti(pid_array, sorted_indices, "compare_paths") | |
for (i = 1; i <= n; i++) { | |
split(pid_array[sorted_indices[i]], data, "|") | |
username = sprintf("%s%-*s%s", YELLOW, user_width, data[1], RESET) | |
pid = sprintf("%s%-*s%s", GREEN, pid_width, data[2], RESET) | |
cpu = sprintf("%s%4s%s", BLUE, data[3], RESET) | |
mem = sprintf("%s%4s%s", MAGENTA, data[4], RESET) | |
status = sprintf("%s%-*s%s", CYAN, status_width, data[5], RESET) | |
script_path = data[6] | |
split(script_path, path_parts, "/") | |
if (length(path_parts) == 3) { | |
colored_command = sprintf("%s%s%s/%s%s/%s%s", RED, path_parts[1], BLUE, path_parts[2], GREEN, path_parts[3], RESET) | |
} else if (length(path_parts) == 2) { | |
colored_command = sprintf("%s%s%s/%s%s", BLUE, path_parts[1], GREEN, path_parts[2], RESET) | |
} else { | |
colored_command = sprintf("%s%s%s", GREEN, script_path, RESET) | |
} | |
# Truncate command if needed | |
visible_length = length(script_path) | |
if (visible_length > cmd_width) { | |
script_path = substr(script_path, 1, cmd_width - 3) "..." | |
visible_length = length(script_path) | |
# Recreate colored command with truncated path | |
split(script_path, path_parts, "/") | |
if (length(path_parts) == 3) { | |
colored_command = sprintf("%s%s%s/%s%s/%s%s", RED, path_parts[1], BLUE, path_parts[2], GREEN, path_parts[3], RESET) | |
} else if (length(path_parts) == 2) { | |
colored_command = sprintf("%s%s%s/%s%s", BLUE, path_parts[1], GREEN, path_parts[2], RESET) | |
} else { | |
colored_command = sprintf("%s%s%s", GREEN, script_path, RESET) | |
} | |
} | |
# Pad the colored_command | |
padding_length = cmd_width - visible_length | |
padding = "" | |
for (j = 0; j < padding_length; j++) { | |
padding = padding " " | |
} | |
colored_command = colored_command padding | |
printf "│%s│%s│%s│%s│%s│%-*s│\n", username, pid, cpu, mem, status, cmd_width, colored_command | |
} | |
bottom = sprintf("└%s┴%s┴%s┴%s┴%s┴%s┘", rep("─", user_width), rep("─", pid_width), rep("─", cpu_width), rep("─", mem_width), rep("─", status_width), rep("─", cmd_width)) | |
printf "%s\n", bottom | |
} | |
function rep(c, n, s) { | |
while (n-- > 0) s = s c | |
return s | |
} | |
function compare_paths(i1, v1, i2, v2) { | |
split(v1, a1, "|") | |
split(v2, a2, "|") | |
path1 = a1[6] | |
path2 = a2[6] | |
# Extract the first directory | |
split(path1, dir1, "/") | |
split(path2, dir2, "/") | |
# Compare first directories | |
if (dir1[1] < dir2[1]) return -1 | |
if (dir1[1] > dir2[1]) return 1 | |
# If first directories are the same, compare full paths | |
if (path1 < path2) return -1 | |
if (path1 > path2) return 1 | |
return 0 | |
} | |
function get_uptime_str(seconds) { | |
if (seconds < 60) return seconds "s" | |
if (seconds < 3600) return int(seconds/60) "m" | |
if (seconds < 86400) return int(seconds/3600) "h" | |
if (seconds < 604800) return int(seconds/86400) "d" | |
if (seconds < 2592000) return int(seconds/604800) "w" | |
return int(seconds/2592000) "mo" | |
} | |
' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment