2018.08.20

使用自动安装drcom的shell脚本之后,打开配置界面,进行认证之后,想起昨晚有那么一瞬间发现,在drcom的luci界面配置以及apply之后,ps -w会出现两条python drcom的进程,于是再次打开putty查看,果然不出所料,于是就有了这篇文章

#!/bin/sh /etc/rc.common
run_drcom()
{
local username
local password
config_get username $1 username
config_get password $1 password
python /usr/bin/drcom -u $username -p $password &
}
start()
{
config_load drcom
config_foreach run_drcom login
}
stop()
{
ps w | grep ".*drcom.*" | grep -v 'grep' | cut -c 2-5 | xargs kill -9
echo "Drcom Client for GDUFE has stoped."
}
  • 大二的时候,在写了drcom的luci界面之后,发现有时候使用drcom_client的stop命令会不奏效,经过查看代码,发现问题应该出在cut -c 2-5

    for example

  • cut -c 2-5 是截取了第二到第五位的字符串 即4位pid

  • 若pid大于4位之后便不再好使

我有印象当时已经改正了,这次出现的 drcom_client 脚本,便是原原本本的当年的模样,至于为什么会这样,可能当时我只改了路由器上的脚本,而没有更新本地脚本

不过,这次的问题不在这里,而是这次的问题,暴露了这个潜在的问题

这次的问题的导火索是

local fs = require "nixio.fs"
local sys = require "luci.sys"
m = Map("drcom",translate("Dr.com configure"),translate("GDUFE Dr.com client configure"))
s = m:section(TypedSection,"login")
s.anonymous = true


name = s:option(Value, "username", translate("Username"))
pass = s:option(Value, "password", translate("Password"))
pass.password = true

local apply = luci.http.formvalue("cbi.apply")
if apply then
    io.popen("/etc/init.d/drcom_client start")
end

return m

原来是apply这段,我记得当时也改过了,可是,这就是咸丰年的那一版。。。

  • 我想在io.popen("/etc/init.d/drcom_client start")上面加上一段io.popen("/etc/init.d/drcom_client stop")就完事了,可是,完美主义并不允许我这么做。

  • 我想,在Drcom_AutoLink上也是一个 stop 一个 start 这样也太low了吧,为什么不给drcom_client写一个restart呢,像service network restart用的多顺手。

  • 二话不说,打开/etc/init.d/drcom_client 添上一段

    restart(){
    stop
    sleep 1
    start
    }
    

    可是每次执行/etc/init.d/drcom_client restart就只有一句Killed,就啥反应也没有了,就连echo "Drcom Client for GDUFE has stoped."这句也没输出

    • restart没反应对吧,一句一句来,先/etc/init.d/drcom_client stop,奇了怪了,echo "Drcom Client for GDUFE has stoped."同样没输出,我就纳闷了
    • 难道是restart没重写成功?
    • 难道是stop没重写成功?

    • 当我去掉ps w | grep ".*drcom.*" | grep -v 'grep' | cut -c 2-5 | xargs kill -9这一句后,echo "Drcom Client for GDUFE has stoped."竟然成功输出了

    • 于是想到,应该是这句把自己也kill掉了,于是去掉| xargs kill -9只留下ps w | grep ".*drcom.*" | grep -v 'grep' | cut -c 2-5

    • 执行/etc/init.d/drcom_client stop,果然,出现了两个pid,在前面再加一句ps -w看看结果

    Solution

    • 1.修复只截取4位pid

    • 2.精准匹配进程名称

    • 修改ps w | grep ".*drcom.*" | grep -v 'grep' | cut -c 2-5 | xargs kill -9

    • ps w | grep "python.*.drcom" |grep -v 'grep'| awk '{print $1}'| xargs kill -9

    • 3.测试restart是否成功

    修改的drcom_client如下

    #!/bin/sh /etc/rc.common
    START=10
    STOP=15
    run_drcom()
    {
    local username
    local password
    config_get username $1 username
    config_get password $1 password
    python /usr/bin/drcom -u $username -p $password &
    }
    start()
    {
    config_load drcom
    config_foreach run_drcom login
    }
    stop()
    {
    ps w | grep "python.*.drcom" |grep -v 'grep'| awk '{print $1}'| xargs kill -9
    echo "Drcom Client for GDUFE has stoped."
    }
    restart(){
    stop
    sleep 1
    start
    }