Never for loop the results of a shell command if you want to process it line by line, unless you change the value of the internal field delimiter $IFS to \n . This is due to the fact that the lines will be subject to word splitting, which will lead to the actual results that you see. If you, for example, have a file like this:
foo bar hello world
Below for the cycle
for i in $(cat file); do echo "$i" done
gives you:
foo bar hello world
Even if you use IFS='\n' , strings may still be perceived as a file name extension
I recommend using while + read , because read is read line by line.
Also, I would use pgrep if you are looking for pids belonging to a specific binary. However, since python can appear as different binary files, like python2.7 or python3.4 , I suggest passing -f to pgrep , which causes it to search the entire command line, rather than just looking for binary files called python . But it will also find processes that were started as cat foo.py You have been warned! At the end, you can refine the regular expression passed to pgrep as you wish.
Example:
pgrep -f python | while read -r pid ; do echo "$pid" done
or if you also want the process name:
pgrep -af python | while read -r line ; do echo "$line" done
If you want the process name and pid to be in separate variables:
pgrep -af python | while read -r pid cmd ; do echo "pid: $pid, cmd: $cmd" done
You see, read offers a flexible and stable way to handle command line output.
Btw, if you prefer your command line ps .. | grep ps .. | grep on top of pgrep used the following loop:
ps -ewo pid,etime,cmd | grep python | grep -v grep | grep -v sh \ | while read -r pid etime cmd ; do echo "$pid $cmd $etime" done
Notice how I etime and cmd . Thus, to read cmd , which may contain spaces, in a single variable. This works because read will break the string into variables, as many times as the variables you specified. The rest of the line — possibly including a space — will be assigned to the last variable specified on the command line.