Skip to content

Instantly share code, notes, and snippets.

@JKc66
Last active March 28, 2025 19:34
Show Gist options
  • Save JKc66/2ecc291f7f494d1cdf6f6479cfa0a86c to your computer and use it in GitHub Desktop.
Save JKc66/2ecc291f7f494d1cdf6f6479cfa0a86c to your computer and use it in GitHub Desktop.
to view python scripts running by user ubuntu
#!/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