Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过PHP运行两个linux命令,不要等到第一个命令结束后再执行第二个命令_Php_Linux_Bash_Centos_Centos6 - Fatal编程技术网

通过PHP运行两个linux命令,不要等到第一个命令结束后再执行第二个命令

通过PHP运行两个linux命令,不要等到第一个命令结束后再执行第二个命令,php,linux,bash,centos,centos6,Php,Linux,Bash,Centos,Centos6,这很奇怪,我搜索并尝试了一切,但我想我只是犯了一个愚蠢的语法错误 我试图在CPU上运行一个压力测试,然后立即将其CPU使用率限制在30%,所有这些都是通过PHP实现的。测试也在另一个用户下使用指定的名称运行,因此可以对其进行限制。压力测试开始时很好,但我可以看到PHP文件仍在加载,并且在压力测试结束的第二天就结束了 以下是我尝试过的一些方法 $output = exec('sudo runuser -l test -c "exec -a MyUniqueProcessName stress -c

这很奇怪,我搜索并尝试了一切,但我想我只是犯了一个愚蠢的语法错误

我试图在CPU上运行一个压力测试,然后立即将其CPU使用率限制在30%,所有这些都是通过PHP实现的。测试也在另一个用户下使用指定的名称运行,因此可以对其进行限制。压力测试开始时很好,但我可以看到PHP文件仍在加载,并且在压力测试结束的第二天就结束了

以下是我尝试过的一些方法

$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"');
这样做的全部目的是因为我正在为一个游戏托管网站编写一个脚本,我想限制每个服务器的资源消耗,以提高质量,而不是让某人占用所有资源。 基本上,将运行游戏服务器,而不是压力测试

编辑::

以下是我现在拥有的:

我需要在测试下运行压力,但cpulimit需要在sudoapache或root下运行,因为它需要特殊权限。压力开始时仍然很好,但它会吃掉99.9%

passthru('sudo runuser -l test -c "exec -a MyUniqueProcessName stress -c 1 -t 60s &" & sudo cpulimit -e MyUniqueProcessName -l 30 -i -z');
执行此操作后,我无法在进程列表中看到cpulimit

不幸的是,&&的操作或多或少与您想要的相反。:-在Bash中执行A&&B时,这意味着运行命令A并等待它完成;如果成功,则运行命令B

相反,A&B意味着先运行命令A,然后立即运行命令B

因此,您的命令已经接近正确,但是仅仅使用两个bash命令就被绊倒了,应该只需要一个和&&

另外,您是否尝试在PHP之外的两个终端上分别运行每个命令?我刚刚下载并构建了这两个命令,我假设这些是您正在使用的,分别运行了这些命令,发现了一个问题:cpulimit仍然没有限制百分比

查看文档中的压力,我发现它是通过分叉子进程来工作的,因此您试图限制CPU的是父进程,但这不是使用CPU的进程。cpulimit-help揭示了option-i,它在有限的范围内包含子进程

这使我能够在一个终端中输入,第一行在提示符处显示输入;后续节目输出:

$> 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
然后,在另一个运行在顶部的终端中,我看到:

好多了。请注意,在bashshell外部,您将其别名为exec-a,您将看到进程名为stress。不幸的是,我还看到了另一个问题,即cpulimit仍在侦听更多具有该名称的进程。回到cpulimit-help,它显示了-z选项

为了稍微降低复杂性,可以关闭别名,通过特殊的Bash变量$!,使用压力过程的PID!,它是指上次启动的进程的PID。在终端中运行以下各项似乎可以实现您想要的一切:

stress -c 1 -t 60s & cpulimit -p $! -l 30 -i -z
现在,用我们学到的内容更改PHP脚本:

exec('bash -c "exec -a MyUniqueProcessName stress -c 1 -t 60s & cpulimit -e MyUniqueProcessName -l 30 -i -z"');
…或更简单的版本:

exec('bash -c "stress -c 1 -t 60s & cpulimit -p \$! -l 30 -i -z"');
注意$中的$!必须用反斜杠“\$!”进行转义!,因为它在传递给bash-c时引用的方式

最后答覆:

根据您对问题所做的最后一个修改示例,您将需要以下内容:

passthru('bash -c "sudo -u test stress -c 1 -t 60s & sudo -u root cpulimit -p \$! -l 30 -i -z"');
当我使用php stackoverflow-question.php运行此程序时,它会输出以下内容:

stress: info: [3374] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
stress: info: [3374] successful run completed in 60s
Process 3371 found
后两行仅在PHP脚本完成后出现,因此不要误导。使用顶部进行检查

在PHP脚本运行的60秒内,在另一个终端上运行top,我看到:

  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
这正是您所描述的:stress在用户测试下运行,cpulimit在用户根目录下运行,如果需要,您可以在命令中更改这两者。压力限制在30%左右

我不熟悉runuser,也不了解其适用性,因为sudo是作为另一个用户运行流程的标准方式。要使其正常工作,您可能需要调整/etc/sudoers中的设置,这将需要root访问权限,但您显然已经拥有了该权限。这完全超出了本文讨论的范围,但作为示例,我添加了以下规则:

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

它仍然做同样的事情,运行压力测试然后冻结,如果我消除压力或让它完成,那么它将执行限制php页面保持加载直到我这样做php页面将保持加载直到bash进程完成,也就是说,两个进程都完成。看起来您使用cpulimit的方式导致了问题。我的系统上没有压力或cpulimit,但下载并构建了它们,并解决了这些问题。请看修改后的答案。非常感谢您的输入。使用的两个命令实际上是stress和cpulimit,是的,我试着从控制台运行它们。它似乎对名字不起作用,但对PID来说它是deff。很好。使用上一次启动的pid不会在具有24个内核的服务器上引起问题吗?错误的过程受到限制?我非常害怕在我的单线程安全泡泡电流imple之外做这样的事情 心理状态和一些更多的信息在OP中,请查看
my-user ALL=(test) NOPASSWD:NOEXEC: /home/my-user/development/stackoverflow/stress 
my-user ALL=(root) NOPASSWD:NOEXEC: /home/my-user/development/stackoverflow/cpulimit