Saya menemukan Anda dapat melakukan ini hanya menggunakan tanda kutip ganda:
while read -r proc; do
#do work
done <<< "$(ps -ewo pid,cmd,etime | grep python | grep -v grep | grep -v sh)"
Ini akan menyimpan setiap baris ke larik daripada setiap item.
Jangan pernah for
ulangi hasil perintah shell jika Anda ingin memprosesnya baris demi baris kecuali jika Anda mengubah nilai pemisah bidang internal $IFS
ke \n
. Hal ini karena baris akan mendapatkan subjek pemisahan kata yang mengarah ke hasil aktual yang Anda lihat. Artinya jika Anda misalnya memiliki file seperti ini:
foo bar
hello world
Berikut untuk loop
for i in $(cat file); do
echo "$i"
done
memberi Anda:
foo
bar
hello
world
Bahkan jika Anda menggunakan IFS='\n'
baris mungkin masih tunduk pada Ekspansi nama file
Saya merekomendasikan untuk menggunakan while
+ read
bukan karena read
membaca baris demi baris.
Selanjutnya saya akan menggunakan pgrep
jika Anda mencari pid milik biner tertentu. Namun, karena python mungkin muncul sebagai binari yang berbeda, seperti python2.7
atau python3.4
Saya sarankan untuk meneruskan -f
ke pgrep
yang membuatnya mencari seluruh baris perintah daripada hanya mencari binari yang disebut python
. Tapi ini juga akan menemukan proses yang telah dimulai seperti cat foo.py
. Anda telah diperingatkan! Pada akhirnya Anda dapat menyempurnakan regex yang diteruskan ke pgrep
seperti yang Anda inginkan.
Contoh:
pgrep -f python | while read -r pid ; do
echo "$pid"
done
atau jika Anda juga menginginkan nama proses:
pgrep -af python | while read -r line ; do
echo "$line"
done
Jika Anda ingin nama proses dan pid dalam variabel terpisah:
pgrep -af python | while read -r pid cmd ; do
echo "pid: $pid, cmd: $cmd"
done
Soalnya, read
menawarkan cara yang fleksibel dan stabil untuk memproses keluaran baris perintah demi baris.
Btw, jika Anda lebih suka ps .. | grep
Anda baris perintah melalui pgrep
gunakan loop berikut:
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
Perhatikan bagaimana saya mengubah urutan etime
dan cmd
. Demikian untuk dapat membaca cmd
, yang dapat berisi spasi putih, menjadi satu variabel. Ini berfungsi karena read
akan memecah garis menjadi variabel, sebanyak yang Anda tentukan variabel. Bagian baris yang tersisa - mungkin termasuk spasi - akan ditetapkan ke variabel terakhir yang telah ditentukan di baris perintah.
Saat menggunakan for
loop di bash itu membagi daftar yang diberikan secara default dengan whitespaces
, ini dapat diadaptasi dengan menggunakan apa yang disebut Pemisah Bidang Internal , atau IFS
singkatnya .
IFS Pemisah Bidang Internal yang digunakan untuk pemisahan kata setelah perluasan dan untuk memisahkan baris menjadi kata dengan perintah bawaan baca. Nilai defaultnya adalah "".
Sebagai contoh Anda, kami perlu memberi tahu IFS
untuk menggunakan new-lines
sebagai titik istirahat.
IFS=$'\n'
for tbl in $(ps -ewo pid,cmd,etime | grep python | grep -v grep | grep -v sh)
do
echo $tbl
done
Contoh ini mengembalikan keluaran berikut pada mesin saya.
668 /usr/bin/python /usr/bin/ud 03:05:54
27892 python 00:01