“Ps aux | lebih elegan grep -v grep ”

177

Ketika saya memeriksa daftar proses dan 'mengambil' yang menarik bagi saya, grepitu sendiri juga termasuk dalam hasil. Misalnya, untuk mencantumkan terminal:

$ ps aux  | grep terminal
user  2064  0.0  0.6 181452 26460 ?        Sl   Feb13   5:41 gnome-terminal --working-directory=..
user  2979  0.0  0.0   4192   796 pts/3    S+   11:07   0:00 grep --color=auto terminal

Biasanya saya gunakan ps aux | grep something | grep -v grepuntuk menyingkirkan entri terakhir ... tetapi tidak elegan :)

Apakah Anda memiliki peretasan yang lebih elegan untuk menyelesaikan masalah ini (selain membungkus semua perintah ke dalam skrip terpisah, yang juga tidak buruk)

Jakub M.
sumber
4
Untuk apa nilainya, ini adalah FAQ kuno. Lihat item 3.10 di faqs.org/faqs/unix-faq/faq/part3
tripleee
1
Terima kasih untuk referensi. Itu metode mereka:ps ux | awk '/name/ && !/awk/ {print $2}'
Jakub M.
Apa yang sedang dilakukan grep -v grepbagian itu?
Jwan622
2
@ Jwan622 grep -v grepdikecualikan grepdari hasil grep. Jika grep digunakan dalam kombinasi dengan ps, maka proses grep (dengan argumen grep) akan ditampilkan juga, mengacaukan hasil Anda. grep -v grep adalah cara umum untuk menghindarinya
Eugene Platonov

Jawaban:

282

Teknik yang biasa adalah ini:

ps aux | egrep '[t]erminal'

Ini akan cocok dengan baris yang mengandung terminal, yang egrep '[t]erminal'tidak! Ini juga berfungsi pada banyak rasa Unix.

Johnsyweb
sumber
1
Ini berfungsi untuk saya untuk string arbitrer, tetapi tidak untuk nama pengguna, mis ps aux | grep '[r]oot'. Adakah yang tahu mengapa?
kxsong
2
@ kxsong: | grep '[t]erminal'memilih baris yang berisi kata 'terminal' tanpa memasukkan kata 'terminal' ke dalam daftar proses. Apa yang ingin Anda capai | grep '[r]oot'dan bagaimana cara kerjanya? Kemungkinan ada solusi yang lebih baik.
Johnsyweb
3
Koreksi saya jika saya salah, tetapi ini juga harus berfungsi pada posisi apa pun dari karakter grepped: ps aux | grep "te [r] minal"
meso_2600
2
hack brilian (saya pikir saya harus menyebutnya begitu, karena penulis aux / grep mungkin tidak memikirkan skenario ini.)
Michael Trouw
2
@JamieJag: Yah ... seperti yang saya katakan di posting saya, grep '[t]erminal'akan cocok dengan baris yang berisi terminal. Output dari ps auxakan memiliki garis dengan grep '[t]erminal'(dengan tanda kurung siku), yang tidak mengandung string terminal(tanpa yang sama).
Johnsyweb
57

Gunakan pgrep . Ini lebih bisa diandalkan.

DarkDust
sumber
pgreptidak akan bekerja jika saya mencari contoh untukps aux | grep 'ssh options'
Jakub M.
12
Jakub M .: Bagaimana pgrep -f?
hillu
4
@ jakub-m Secara default pgrephanya cocok dengan pola terhadap nama proses. Untuk mencocokkan dengan seluruh perintah, gunakan -fbendera.
bluecollarcoder
3
pgrephanya mengembalikan ID proses.
Melab
1
versi yang lebih lama mengambil pgrep -fl(tetapi tidak bisa melihat cmdline penuh tanpa -fmencocokkan cmdline penuh, detail: serverfault.com/a/619788/44183 ). Tapi ya jika Anda memerlukan info lain selain pid, cmdline, Anda perlu ps. Dapat menggabungkan mereka:ps -p $(pgrep -f foo)
Beni Cherniavsky-Paskin
29

Jawaban ini dibangun berdasarkan pgrep jawaban sebelumnya . Itu juga dibangun di atas jawaban lain yang menggabungkan penggunaan psdengan pgrep. Berikut adalah beberapa contoh pelatihan terkait:

$ pgrep -lf sshd
1902 sshd

$ pgrep -f sshd
1902

$ ps up $(pgrep -f sshd)
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      1902  0.0  0.1  82560  3580 ?        Ss   Oct20   0:00 /usr/sbin/sshd -D

$ ps up $(pgrep -f sshddd)
error: list of process IDs must follow p
[stderr output truncated]

$ ps up $(pgrep -f sshddd) 2>&-
[no output]

Di atas dapat digunakan sebagai fungsi :

$ psgrep() { ps up $(pgrep -f $@) 2>&-; }

$ psgrep sshd
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      1902  0.0  0.1  82560  3580 ?        Ss   Oct20   0:00 /usr/sbin/sshd -D

Bandingkan dengan menggunakan psdengan grep. Baris tajuk yang bermanfaat tidak dicetak:

$  ps aux | grep [s]shd
root      1902  0.0  0.1  82560  3580 ?        Ss   Oct20   0:00 /usr/sbin/sshd -D
Acumenus
sumber
Lihat github.com/blueyed/oh-my-zsh/blob/… (tetapi khusus untuk Zsh).
blueyed
@ blueyed, saya telah memperbarui jawabannya dengan definisi fungsi bash.
Acumenus
Perhatikan juga -dopsi untuk menentukan pemisah; mis.ps -fp$(pgrep -d , getty)
Toby Speight
1
Saya menggunakan ini: ps uxp `pgrep <process>` Catatan yang pharus menjadi parameter terakhir (yaitu, puxtidak akan berfungsi)
KFL
9

Anda dapat memfilter dalam perintah ps, mis

ps u -C gnome-terminal

(atau cari melalui / proc dengan find dll)

Andreas Frische
sumber
1
Perhatikan bahwa ini berfungsi dengan ps GNU (Linux), tetapi tidak dengan BSD ps.
Josh
Ini tidak benar bahkan dengan GNU ps. ps -C <command>akan cocok dengan perintah yang tepat. Ketika digunakan dengan opsi aatau xitu akan melaporkan semua proses, karena adan xdaftar proses di samping serangkaian proses yang cocok dengan cara lain.
Animisme
@Animisme Benar. Terima kasih, saya memperbaikinya.
Andreas Frische
Ini hanya berfungsi jika nama proses ditentukan dengan tepat. Ini tidak berfungsi untuk kecocokan sebagian, misalnya loginduntuk systemd-logind, atau untuk mencocokkan argumen.
Acumenus
4

Satu lagi alternatif :

ps -fC terminal

Di sini opsinya:

 -f        does full-format listing. This option can be combined
           with many other UNIX-style options to add additional
           columns. It also causes the command arguments to be
           printed. When used with -L, the NLWP (number of
           threads) and LWP (thread ID) columns will be added. See
           the c option, the format keyword args, and the format
           keyword comm.

 -C cmdlist     Select by command name.
                This selects the processes whose executable name is
                given in cmdlist.
TaXXoR
sumber
6
Kelemahan kecil, dan salah satu yang tidak benar-benar terkait dengan pertanyaan OP, adalah bahwa ini tidak akan menunjukkan kepada Anda hal-hal seperti Tomcat, yang sebenarnya dijalankan sebagai java dengan daftar argumen.
Charles Wood
-COpsi sudah disarankan dalam jawaban @Andreas Frishe yang diposting lebih dari satu setengah tahun sebelumnya ...
Piotr Dobrogost
3

Menggunakan tanda kurung untuk mengelilingi karakter dalam pola pencarian tidak termasuk grepproses karena tidak mengandung regex yang cocok.

$ ps ax | grep 'syslogd'
   16   ??  Ss     0:09.43 /usr/sbin/syslogd
18108 s001  S+     0:00.00 grep syslogd

$ ps ax | grep '[s]yslogd'
   16   ??  Ss     0:09.43 /usr/sbin/syslogd

$ ps ax | grep '[s]yslogd|grep'
   16   ??  Ss     0:09.43 /usr/sbin/syslogd
18144 s001  S+     0:00.00 grep [s]yslogd|grep
auntchilada
sumber
3

Penafian: Saya pembuat alat ini, tapi ...

Saya akan menggunakan px :

~ $ px atom
  PID COMMAND          USERNAME   CPU RAM COMMANDLINE
14321 crashpad_handler walles   0.01s  0% /Users/walles/Downloads/Atom.app/Contents/Frameworks/Electron Framework.framework/Resources/crashpad_handler --database=
16575 crashpad_handler walles   0.01s  0% /Users/walles/Downloads/Atom.app/Contents/Frameworks/Electron Framework.framework/Resources/crashpad_handler --database=
16573 Atom Helper      walles    0.5s  0% /Users/walles/Downloads/Atom.app/Contents/Frameworks/Atom Helper.app/Contents/MacOS/Atom Helper --type=gpu-process --cha
16569 Atom             walles   2.84s  1% /Users/walles/Downloads/Atom.app/Contents/MacOS/Atom --executed-from=/Users/walles/src/goworkspace/src/github.com/github
16591 Atom Helper      walles   7.96s  2% /Users/walles/Downloads/Atom.app/Contents/Frameworks/Atom Helper.app/Contents/MacOS/Atom Helper --type=renderer --no-san

Kecuali untuk menemukan proses dengan antarmuka baris perintah yang masuk akal itu juga melakukan banyak hal berguna lainnya, lebih detail di halaman proyek .

Bekerja di Linux dan OS X, mudah diinstal:

curl -Ls https://github.com/walles/px/raw/python/install.sh | bash
Johan Walles
sumber
0

Tergantung pada kasus penggunaan utama, Anda sering ingin lebih memilih Awk.

ps aux | awk '/[t]erminal/'

Ini terutama benar ketika Anda memiliki sesuatu seperti

ps aux | grep '[t]erminal' | awk '{print $1}'  # useless use of grep!

di mana jelas regex dapat diperhitungkan dalam skrip Awk sepele:

ps aux | awk '/[t]erminal/ { print $1 }'

Tapi sungguh, jangan menemukan kembali ini sendiri. pgrepdan teman-teman telah ada sejak lama dan menangani seluruh ruang masalah ini jauh lebih baik daripada kebanyakan implementasi ad hoc.

tripleee
sumber
-2

Pilihan lain adalah mengedit .bash_profile(atau file lain tempat Anda menyimpan alias bash) untuk membuat fungsi yang mengeluarkan 'grep' dari hasilnya.

function mygrep {
grep -v grep | grep --color=auto $1
}

alias grep='mygrep'

Itu grep -v grepharus menjadi yang pertama jika bukan Anda--color=auto tidak akan berhasil karena suatu alasan

Ini berfungsi jika Anda menggunakan bash; jika Anda menggunakan shell YMMV yang berbeda.

FlyingCodeMonkey
sumber
1
Ada apa dengan alias dan fungsinya? Lakukan saja function grep { command grep -v grep | command grep --color=auto "$@"; }(perhatikan juga argumen dan kutipannya). Namun, ini rusak karena non- psdoa greptidak lagi berfungsi (argumen dilewatkan secara tidak benar). Pokoknya, fungsi yang jauh lebih bermanfaat adalah yang memodifikasi regex agar tidak cocok dengan dirinya sendiri, daripada memfilter grepdari grephasil secara terpisah. Dan tentu saja, menemukan solusi baru untuk masalah yang telah dipecahkan secara memadai beberapa dekade yang lalu tidak terlalu produktif.
tripleee