so true

心怀未来,开创未来!
随笔 - 160, 文章 - 0, 评论 - 40, 引用 - 0
数据加载中……

Linux下修改后的ps命令,很好很强大!

今天在linux下写了个小程序,功能是:利用ps来查找包含当前字符串的所有命令,有时候会得到很多搜索结果,而且由于每个命令附带的参数很长,导致很乱很难以分清楚,下面这个程序会将匹配得到的结果每隔一行输出,而且搜索词会以红色加粗显示,并且搜索结果会被两条彩色线条分隔出来,该彩色线条的颜色和线型也都是随机变换的,这么做的目的是为了防止在一屏内的两次结果的四条线之间混乱,用不同颜色和线型加以区分会非常清晰明了,而且该彩色线条的长度是与你的终端宽度相匹配的;后续又改进了一下,比如你搜索mps Sh,那么可以为你搜索出mps SH;mps sh; mps sH; mps Sh四种结果的并集。

先看一下shell版本的:
#!/bin/bash

if [ "$#" -ne "1" ];then
    echo "Usage: my <SearchWord>"
    exit 1
fi

COLORTYPE=$((32+RANDOM%5))
lineArray=('=' '-' '#' '%' '~' '/')
LINETYPE=${lineArray[$((RANDOM%6))]}

echo -e "\033[1;${COLORTYPE}m`python -c "print ""'"${LINETYPE}"'"*$(echo  $(stty size) | cut -d' ' -f2)`\033[0m"
echo
ps aux | grep -i $1 | awk "!/grep/&&!/mps.*$1/&&!/sed.*$1.*1;31m.*g/{print \$0 \"\n\" }" | sed -e "s/\($1\)/$(echo -e '\033')\[1;31m\1$(echo -e '\033')\[0m/gi"
#需要说明的是,上面的$(echo -e '\033')完全可以由字符^[,注意这是一个字符,表示Esc那个键,在vi里可以通过Ctrl+v,然后再按Esc来输入该特殊字符;这里用echo这么恶心的做法只是因为我如果写^[这个字符,怕误导大家以为是两个字符,因此给出了一个通用的,不会有歧义的,但是也很丑陋的做法
echo -e "\033[1;${COLORTYPE}m`python -c "print ""'"${LINETYPE}"'"*$(echo  $(stty size) | cut -d' ' -f2)`\033[0m"

再给出c++版本的(其实上面的shell版本已经足够了,不过当初我没把shell实现的那么完整,后来才发现原来shell都可以实现之,因此下面的 c++版本纯粹是为了自我留念之用,大家可以不必看了,呵呵):
#include <termio.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <string>
#include <time.h>

using namespace std;

enum Color
{
    GREEN = 32,
    YELLOW = 33,
    BLUE = 34,
    MAUVE = 35,
    CYANINE = 36
};

enum LineStyle
{
    EQUAL = (uint32_t) '=',
    TILDE = (uint32_t) '~',
    ASTERISK = (uint32_t) '*',
    MINUS = (uint32_t) '-',
    POUND = (uint32_t) '#',
    SLASH = (uint32_t) '/'
};

uint32_t ChooseColor()
{
    srand(static_cast<unsigned>(time(0)));

    switch(rand()%5)
    {
    case 0:
        return GREEN;
        break;
    case 1:
        return YELLOW;
        break;
    case 2:
        return BLUE;
        break;
    case 3:
        return MAUVE;
        break;
    default:
        return CYANINE;
        break;
    }

    return GREEN;
}

uint32_t ChooseLineStyle()
{
    srand(static_cast<unsigned>(time(0)));

    switch(rand()%6)
    {
    case 0:
        return EQUAL;
        break;
    case 1:
        return TILDE;
        break;
    case 2:
        return ASTERISK;
        break;
    case 3:
        return MINUS;
        break;
    case 4:
        return POUND;
        break;
    default:
        return SLASH;
        break;
    }

    return EQUAL;
}

int main(int argc, char* argv[])
{
    if (2 != argc)
    {
        cout << "Usage: mps <SearchWord>" << endl;
        return 1;
    }

    struct winsize wsz;
    ioctl(STDOUT_FILENO, TIOCGWINSZ, (char*) &wsz);

    stringstream seperatorLine;
    seperatorLine << "echo """ << (char)27 << "[1;" << ChooseColor() << 'm'
    << string("").append(wsz.ws_col, (char)ChooseLineStyle()) << char(27) << "[0m""";

    char psCommand[1024] = {0};
    sprintf(psCommand,"ps aux | grep %s | grep -v grep | grep -v 'mps.*%s' | grep -v 'sed.*%s.*""[1;31m%s.*g' | "
                "awk '{print $0 """"n""}' | sed ""s/%s/%c""[1;31m%s%c""[0m/g""",
                argv[1], argv[1], argv[1], argv[1], argv[1], (char)27, argv[1], (char)27);

    system(seperatorLine.str().c_str());
    system("echo");
    system(psCommand);
    system(seperatorLine.str().c_str());

    return 0;
}

最后给出使用方法,不论是shell版本的还是binary版本的,都需要其有可执行权限,我是将其拷贝到/usr/bin目录下了,这样大家就都可以使用该程序了:mps vmware即可; 后来又想到更简单的办法,直接在.bashrc中定义个函数叫mps即可,把上面的shell代码copy到函数体里面(将exit 1换为return)就ok了。

posted on 2009-06-13 03:34 so true 阅读(1257) 评论(0)  编辑  收藏 所属分类: C&C++Linux


只有注册用户登录后才能发表评论。


网站导航: