0

I am trying to write a bash script to find duplicate instances of python scripts running on a Pi. The following script is working and identifies the Python (not Python3 intentionally) of duplicates instances of the same script. I get the PID as expected but I am not able to get the full path and name of the script.

I have created a couple instance of a script:

bms       9189  0.0  0.1  10592  7248 ?        S    09:11   0:00 python -u /home/bms/Dev/APItest/APItest.py
bms       9192  0.0  0.1  10592  7188 ?        S    09:12   0:00 python -u /home/bms/Dev/APItest/APItest.py

This is the output I get from the bash script:

Found 2 instances of -u:
PID: 9189, Script path: -u
PID: 9192, Script path: -u
Finished checking for duplicate Python scripts.

I was expecting to get an output like:

PID: 9189, Script path: home/bms/Dev/APItest/APItest.py
PID: 9192, Script path: home/bms/Dev/APItest/APItest.py

And this is the script I am using:

#!/bin/bash

# Get a list of all running Python processes
PYTHON_PROCESSES=$(ps aux | grep '[p]ython' | grep -v 'python3' | awk '{print $2}')

# Loop through the Python processes and count how many times each script is running
declare -A SCRIPT_COUNTS
declare -A SCRIPT_PIDS
for PID in $PYTHON_PROCESSES; do
    CMD=$(ps -p $PID -o comm=)
    if [ "$CMD" == "python" ]; then
        SCRIPT_ARGS=$(ps -p $PID -o args=)
        SCRIPT_PATH=$(echo "$SCRIPT_ARGS" | awk '{print $2}')
        SCRIPT_NAME=${SCRIPT_PATH##*/}
        if [ -z "${SCRIPT_COUNTS[$SCRIPT_NAME]}" ]; then
            SCRIPT_COUNTS[$SCRIPT_NAME]=0
        fi
        ((SCRIPT_COUNTS[$SCRIPT_NAME]++))
        if [ -z "${SCRIPT_PIDS[$SCRIPT_NAME]}" ]; then
            SCRIPT_PIDS[$SCRIPT_NAME]=""
        fi
        SCRIPT_PIDS[$SCRIPT_NAME]="${SCRIPT_PIDS[$SCRIPT_NAME]}$PID:$SCRIPT_PATH "
    fi
done

# Loop through the script counts and print the names of any scripts that have     duplicates
for SCRIPT_NAME in "${!SCRIPT_COUNTS[@]}"; do
    COUNT=${SCRIPT_COUNTS[$SCRIPT_NAME]}
    if [ $COUNT -gt 1 ]; then
        echo "Found $COUNT instances of $SCRIPT_NAME:"
        for INSTANCE in ${SCRIPT_PIDS[$SCRIPT_NAME]}; do
            PID=${INSTANCE%%:*}
            SCRIPT_PATH=${INSTANCE#*:}
            echo "PID: $PID, Script path: $SCRIPT_PATH"
        done
       fi
    done

echo "Finished checking for duplicate Python scripts."

Apologise if there is any misalignment in the code. Had to adjust it manually to fit it in the canvas. My question is: what should I change to get the desired output ( PID plus full path and name of the duplicates).

FeliceM
  • 4,163
  • 9
  • 48
  • 75
  • 1
    [Please do not upload images of code/data/errors.](//meta.stackoverflow.com/q/285551) – Gilles Quénot Feb 14 '23 at 08:54
  • @GillesQuénot It is not a code/data/error. It is a screenshot of the files I am processing in terminal. I think it is necessary to clarify the question. – FeliceM Feb 14 '23 at 08:57
  • 1
    This is the same. Cppy your output as text, not images. That way, we can use the input to test your code. Please, read [MCVE](https://stackoverflow.com/help/mcve) – Gilles Quénot Feb 14 '23 at 08:58
  • @GillesQuénot, ok got it. Sorry for that. Fixed – FeliceM Feb 14 '23 at 09:01
  • [Don't use UPPER case variables](https://stackoverflow.com/questions/673055/correct-bash-and-shell-script-variable-capitalization) – Gilles Quénot Feb 14 '23 at 09:14

1 Answers1

1

Why not this simple ?

$ <INPUT> | awk '{print "PID: " $2 ", Script path: " $NF}' file
PID: 9189, Script path: /home/bms/Dev/APItest/APItest.py
PID: 9192, Script path: /home/bms/Dev/APItest/APItest.py
Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223