dongqun5769 2015-03-14 16:43
浏览 127
已采纳

通过PHP运行两个linux命令,在执行第二个之前不要等待第一个结束

This is pretty weird, and I searched and tried everything, but I think I'm just making a dumb syntax error here.

I'm trying to run a stress test on the CPU , then immediately limit it's cpu usage to 30% , all this via PHP. The test is also run under another user and with a specified name so it can be limited. The stress test starts fine, but I can see the PHP file still loading, and it ends the second the stress test ends.

Here's some of the ways I tried doing it

$output = exec('sudo runuser -l test -c "exec -a MyUniqueProcessName stress -c 1 -t 60s & cpulimit -e MyUniqueProcessName -l 30"');

$output = exec('sudo runuser -l test -c "exec -a MyUniqueProcessName stress -c 1 -t 60s > /dev/null & cpulimit -e MyUniqueProcessName -l 30"');

The whole purpose of this is because I am writing a script for a game hosting website, and I want to limit the resource consumption of each server to improve quality and not let someone hog all the resources. Basically, instead of the stress test, a game server will run.

edit::

here's what I have now:

I need to run the stress under "test" , but the cpulimit under either sudo apache or root, because it requires special permissions. The stress still starts fine but it eats 99.9%

passthru('sudo runuser -l test -c "exec -a MyUniqueProcessName stress -c 1 -t 60s &" & sudo cpulimit -e MyUniqueProcessName -l 30 -i -z');

I can't see the cpulimit in the process list after doing this http://i.imgur.com/iK2nL43.png

  • 写回答

1条回答 默认 最新

  • dongxing4196 2015-03-14 22:28
    关注

    Unfortunately, the && does more or less the opposite of what you want. :-) When you do A && B in Bash, that means, "Run command A and wait until it's done; if it succeeded, then run command B."

    By contrast, A & B means, "Run command A and then immediately run command B."

    So you're close to right in your command, but just getting tripped up by using two bash commands (should only need one) and the &&.

    Also, did you try running each command separately, outside PHP, in two terminals? I just downloaded and built both stress and cpulimit (I assume these are the ones you're using?), ran the commands separately, and spotted a problem: cpulimit still isn't limiting the percentage.

    Looking at the docs for stress, I see it works by forking child processes, so the one you're trying to CPU-limit is the parent, but that's not the one using the CPU. cpulimit --help reveals there's option -i, which includes child processes in what is limited.

    This gets me to the point of being able to enter this in one terminal (first line shows input at the prompt; subsequent show output):

    $> exec -a MyUniqueProcessName stress -c 1 -t 60s & cpulimit -e MyUniqueProcessName -l 30 -i
    [1] 20229
    MyUniqueProcessName: info: [20229] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
    Process 20229 found
    

    Then, in another terminal running top, I see:

      PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM     TIME+ COMMAND
    20237 stackov+  20   0  7164  100    0 R 30.2  0.0   0:04.38 stress
    

    Much better. (Notice that outside the Bash shell where you aliased it with exec -a, you will see the process name as stress.) Unfortunately, I also see another issue, which is cpulimit remaining "listening" for more processes with that name. Back to cpulimit --help, which reveals the -z option.

    Just to reduce the complexity a bit, you could leave the alias off and use the PID of the stress process, via the special Bash variable $!, which refers to the PID of the last process launched. Running the following in a terminal seems to do everything you want:

    stress -c 1 -t 60s & cpulimit -p $! -l 30 -i -z
    

    So now, just change the PHP script with what we've learned:

    exec('bash -c "exec -a MyUniqueProcessName stress -c 1 -t 60s & cpulimit -e MyUniqueProcessName -l 30 -i -z"');
    

    ...or, simpler version:

    exec('bash -c "stress -c 1 -t 60s & cpulimit -p \$! -l 30 -i -z"');
    

    (Notice the $ in the $! had to be escaped with a backslash, \$!, because of the way it's quoted when passed to bash -c.)

    Final Answer:

    Based on the last example you amended to your question, you'll want something like this:

    passthru('bash -c "sudo -u test stress -c 1 -t 60s & sudo -u root cpulimit -p \$! -l 30 -i -z"');
    

    When I run this with php stackoverflow-question.php, it outputs the following:

    stress: info: [3374] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
    stress: info: [3374] successful run completed in 60s
    Process 3371 found
    

    (The second two lines only appear after the PHP script finishes, so don't be mislead. Use top to check.)

    Running top in another terminal during the 60 seconds the PHP script is running, I see:

      PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM     TIME+ COMMAND
     3472 test      20   0  7160   92    0 R 29.5  0.0   0:07.50 stress
     3470 root       9 -11  4236  712  580 S  9.0  0.0   0:02.28 cpulimit
    

    This is exactly what you've described wanting: stress is running under the user test, and cpulimit is running under the user root (both of which you can change in the command, if desired). stress is limited to around 30%.

    I'm not familiar with runuser and don't see the applicability, since sudo is the standard way to run a process as another user. To get this to work, you may have to adjust your settings in /etc/sudoers (which will require root access, but you obviously already have that). That's entirely outside the scope of this discussion, but as an example, I added the following rules:

    my-user ALL=(test) NOPASSWD:NOEXEC: /home/my-user/development/stackoverflow/stress 
    my-user ALL=(root) NOPASSWD:NOEXEC: /home/my-user/development/stackoverflow/cpulimit 
    

    展开全部

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
编辑
预览

报告相同问题?

悬赏问题

  • ¥15 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部