Mai for
ciclo sopra i risultati di un comando shell se si desidera elaborare riga per riga a meno che non si sta modificando il valore del separatore di campo interno $IFS
-\n
. Questo perché le linee avranno oggetto della divisione divisione che porta ai risultati effettivi che stai vedendo. Significato se per esempio avete un file in questo modo:
foo bar
hello world
Il seguente ciclo for
for i in $(cat file); do
echo "$i"
done
ti dà:
foo
bar
hello
world
Anche se si utilizza IFS='\n'
le linee potrebbero ancora ottenere soggetto di Filename expansion
Si consiglia di utilizzare while
+ read
invece perché read
legge riga per riga.
Inoltre, vorrei utilizzare pgrep
se si cercano i pid appartenenti a un determinato binario. Tuttavia, dal momento che Python potrebbe apparire come binari diversi, come python2.7
o python3.4
, suggerisco di passare -f
a pgrep
che lo fa cercare nell'intera riga di comando anziché cercare solo i binari chiamati python
. Ma questo troverà anche processi che sono stati avviati come cat foo.py
. Sei stato avvertito! Alla fine puoi perfezionare la regex passata a pgrep
come desideri.
Esempio:
pgrep -f python | while read -r pid ; do
echo "$pid"
done
o se si desidera anche il nome del processo:
pgrep -af python | while read -r line ; do
echo "$line"
done
Se si desidera che il nome del processo e il pid in variabili distinte:
pgrep -af python | while read -r pid cmd ; do
echo "pid: $pid, cmd: $cmd"
done
È vedere, read
offre un modo flessibile e stabile per elaborare l'output di un comando riga per riga.
Btw, se si preferisce la linea di comando ps .. | grep
sopra pgrep
utilizzare il seguente ciclo:
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
Nota come ho cambiato l'ordine delle etime
e cmd
. Pertanto, per poter leggere cmd
, che può contenere spazi bianchi, in una singola variabile. Funziona perché read
divide la riga in variabili, tante volte quante sono le variabili specificate. La parte restante della riga, che potrebbe includere spazi bianchi, verrà assegnata all'ultima variabile che è stata specificata nella riga di comando.
Suppongo che intendessi "pgrep" e non "prep"? – adic26
Oh, certo ....... Btw, se hai bisogno dell'etime, usa 'ps -p" $ pid "-o etime' nel ciclo. Ovviamente puoi anche usare il tuo 'ps .. | grep 'command line, ma ancora pipe a' while read ... '... – hek2mgl
Anche se si imposta' IFS', l'espansione della sostituzione del comando è ancora soggetta all'espansione del pathname, quindi il ciclo 'for' è solo semplicemente sbagliato – chepner