前記事: 任意のプロセス名からそのプログラムの絶対パスを得る - 日々量産
一個の関数で済むようにシェルスクリプトで書き書き。
grep以外は馴染みがないLinux初心者なのでとても苦労しました。
(もしかしたらCentOS 6.0 x86_64以外では動作しないかもしれません)
もっとうまい方法があるような気がしてなりません。
#!/bin/sh if [ $# -ne 1 ] ; then echo usage: $0 [VALUE] exit 1 fi # プロセス名からプロセスID探索 pid(){ PROGRAM=$1 line=$2 TEMP_PID=`echo $line | sed "s#.*/proc/\([0-9]\+\)/.\+#\1#" `; if [ "$line" != "$TEMP_PID" ] ; then PID=$TEMP_PID fi FULLPATH=`echo "$line" | awk '{printf \$12}'` if [ "${PROGRAM:0:1}" != "/" ]; then PROGRAM=/$PROGRAM fi if [ `echo $FULLPATH | grep "$PROGRAM\$"` ] ; then echo "$PID" "$FULLPATH" fi } getpid(){ PROGRAM=$1; IFS=$'\n'; for line in `ls -l /proc/*/exe 2>/dev/null`; do pid $PROGRAM $line done for line in `ls -l /proc/*/fd 2>/dev/null`; do pid $PROGRAM $line done } getpid $1
使い方
こんな感じに使えればーって思ってます
./pid.sh pid.sh | kill `awk '{print $1}'`
- bash: kill: (28188) - そのようなプロセスはありません
同じプロセスが複数ある場合。
./pid.sh sshd
1475 /usr/sbin/sshd
1531 /usr/sbin/sshd
1601 /usr/sbin/sshd
フルパス指定することも出来ます。
同一プログラム名で異なるフォルダに配置されているものもたまにあるので、
それを区別したいときはパスを指定します。
./pid.sh /usr/bin/sshd
1475 /usr/sbin/sshd
1531 /usr/sbin/sshd
1601 /usr/sbin/sshd
(結果はイメージです)
欠点
動作がめちゃんこ遅い。リダイレクトって重いのかなー。それともforあたりかな。
また、プログラム名の探索はgrepを使ってやっているので、
"*"とか入っちゃうと任意長マッチになってしまう。
"mysql*"とすれば、mysqlとmysqldが取得できてしまう。
おまけ(Perl)
プロトタイプでちゃっちゃか書いたもの。
無駄が多いけどシェルスクリプトと比べて速く結果が出る。
#!/usr/bin/perl use strict; use warnings; my $program = $ARGV[0] || die 'usage $0 [PROGRAM_NAME]'; my @line; for my $target ('fd','exe'){ my $ret = `ls -l /proc/*/$target 2>/dev/null | grep -e '$program' -e '^/proc'`; push @line , split(/\r?\n/, $ret); } my $pid; $program = "/$program" if $program !~ /\//; foreach my $line (@line){ my $fullpath = `echo "$line" | awk {'printf \$11'}`; # PID if($line =~ /\/proc\/(\d+)\/(?:fd|exe)/){ $pid = $1; } # program name matching if($fullpath && $fullpath =~ /$program$/){ print "$pid $fullpath\n"; } }