php在前台运行另一个脚本

我有一个php脚本,通过传递参数来运行另一个期望脚本。</ p>

$ output = shell_exec(“expect login_script.tcl'$ user''$ host''$ port''$ password'”);
</ code> </ pre>
\ n

使用shell_exec不起作用,因为脚本在后台运行或在php脚本中运行。 我需要它在前台运行,允许用户交互。 是否有一种优雅的方式来做到这一点。 必须使用不同的脚本语言已经变得混乱了。 我尝试用一​​个调用php脚本的shell脚本包装这两个脚本,将结果作为变量分配输出(这是一个命令)然后运行它。 但是我再次遇到相同的问题,脚本在后台运行,任何用户交互都会产生暂停/冻结。 如果在调用shell exec时php'退出',这种情况就可以了。 IE浏览器。 php停止并期望像你调用它一样运行。 (就像我刚刚复制输出的命令并将其粘贴到终端中一样)。</ p>


更新
我的运气好多了以下 php中的命令:</ p>

  shell_exec(“gnome-terminal -e'bash -c \”expect~ / commands / login_script.tcl; exec bash \“'&amp;”)  ; 
</ code> </ pre>

但是,这可以改进,以便在辅助脚本(login_script)完成后不立即关闭shell吗?</ p>


进一步更新</ p>

通过阅读答案,我认为我需要澄清一些事情,因为看起来人们正在承担一个“更复杂”的问题。</ p>


  • 这两个进程不需要相互通信,我可能不会在示例中放入 $ output = shell_exec </ code> 并且只是 shell_exec </ code>,因为我认为这导致了混乱。</ p> </ li>

  • php脚本只需启动expect脚本 一些cli参数,例如 我的脚本'param1''param2'可以被认为是完全'异步'。 这很像启动程序的行为,如'launchy'或'synapse',它们可以启动其他程序但不需要影响它们。 他们也没有等待二级程序退出/完成。</ p> </ li>

  • 我错误地说'shell_exec'对我不起作用。 我应该说的是'我到目前为止还没有成功使用shell_exec',但 shell_exec(“gnome-terminal -e'bash -c \”expect~ / commands / login_script.tcl; exec bash \“ '&amp;“); </ code>正在'工作',但仍在尝试找到正确的引用组合,以允许将参数传递给expect脚本。</ p> </ li>
    </ ul>
    </ DIV>

展开原文

原文

I have a php script that leads up to running another expect script by passing it arguments.

$output = shell_exec("expect login_script.tcl '$user' '$host' '$port' '$password'");

Using shell_exec doesn't work as the script gets run in the background or 'within' the php script. I need it to run in the foreground, allowing user interactivity. Is there an elegant way to do this. Already it is getting messy by having to use different scripting languages. I tried wrapping the two scripts with a shell script that called the php script, assigned output the result as a variable (which was a command) and then ran sh on that. However I have the same problem again where the scripts are run in the background and any user interactivity creates a halt/freeze. Its ok in this situation if php 'quits' out when calling shell exec. Ie. php stops and expect gets run as if you called it. (the same as if i just copied the command that is output and pasted it into the terminal).


Update I am having much more luck with the following command in php:

shell_exec("gnome-terminal -e 'bash -c \"expect ~/commands/login_script.tcl; exec bash\"' &");

However, can this be improved in order to not close the shell immediately after the secondary script (login_script) is finished?


Further Update

From reading the answers I think I need to clarify things as it looks like people are assuming a 'more complicated' issue.

  • the two processes do not need to communicate with each other, I should probably not have put the $output = shell_exec in the example and just shell_exec on its own as I believe this has led to the confusion.

  • The php script needs to only initiate the expect script with some cli parameters, e.g. my-script 'param1' 'param2' and can be thought of as completely 'asynchronous'. This is much like the behaviour of launcher programs like 'launchy' or 'synapse' they can launch other programs but need not affect them. Nor do they wait for the secondary program to quit/finish.

  • I made the mistake of saying 'shell_exec' doesn't work for me. What I should have said was that 'I have so far not succeeded with using shell_exec', but shell_exec("gnome-terminal -e 'bash -c \"expect ~/commands/login_script.tcl; exec bash\"' &"); is 'working' but still trying to find the right quote combination to allow passing arguments to the expect script.

duansanzi5265
duansanzi5265 php脚本可以从命令行运行。您甚至可以添加一个shebang行并使它们可执行以使它们自动运行。看到这个页面。
7 年多之前 回复
dtkz3186
dtkz3186 两个脚本都将从用户获取输入并基于此执行操作。例如php使用readline()方法,并期望使用获取stdin。脚本根据用户选择的内容执行各种操作。正如我所说,它们是交互式脚本,更像是程序,而不仅仅是执行一长串命令。它们分别运行得很好,但我希望php脚本能够退出并启动expect脚本,而不是让用户手动运行它。
接近 8 年之前 回复
duanjunao9348
duanjunao9348 你要问的是泥浆。它不仅仅是脚本的运行方式,还需要解释它的作用等等。
接近 8 年之前 回复
dqhr76378
dqhr76378 我已经有readlines等...$searchTerm=readline();
接近 8 年之前 回复
dougua9165
dougua9165 您希望用户如何与PHP脚本进行交互?
接近 8 年之前 回复

4个回答



任务管理是一项有趣但困难的工作。</ p>

因为您的用户可以在任务期间移动 (并导致意外结果,例如会话冻结,或者流程中的不完整工作),您需要在后台执行它。 如果您需要在用户和流程之间进行交互,则需要创建一种沟通方式。</ p>

最简单的方法(我认为)是使用您之间共享的文件 用户会话和任务。 </ p>

</ p>

< p>如果您同时拥有大量用户并在用户和进程之间进行大量通信,则可以在内存中安装分区以优化读/写操作。</ p>

在fstab中, 如下所示:</ p>

  tmpfs / memory tmpfs defaults,uid = www-data,gid = www-data,size = 128M 0 0 
</ code> </ pre>

或者,在脚本中,你可以这样做:</ p>

 #!/ bin / sh 
mkfs -t ext2 -q / dev / ram1 65536 \ n [! -d / memory]&amp;&amp; mkdir -p / memory
mount / dev / ram1 / memory
chmod -R 777 / memory
</ code> </ pre>

你需要处理很多事情: </ p>


  • 文件访问(以避免webapp与进程之间的并发)</ li>
  • 时间(避免僵尸或无用的长时间运行的脚本) </ li>
  • 安全性(必须仔细设计此类操作)</ li>
  • 资源管理(以避免10000个进程同时运行)</ li>
  • ... </ li>
    </ ul>
    </ div>

展开原文

原文

Task managing is an interesting but difficult job.

Because your user can move during a task (and leads it to an unexpected result, such as session freezes, or an incomplete work from the process), you need to execute it in background. If you need to interact between your user and your process, you'll need to create a way to communicate.

The easiest way (I think) is to use a file, shared between your user session and the task.

enter image description here

If you have a lot of users simultaneously and communicates a lot between user and processes, you can mount a partition in memory to optimize the read/write operations.

In your fstab, a line like :

tmpfs /memory       tmpfs defaults,uid=www-data,gid=www-data,size=128M 0 0

Or, in a script, you could do :

#!/bin/sh
mkfs -t ext2 -q /dev/ram1 65536
[ ! -d /memory ] && mkdir -p /memory
mount /dev/ram1 /memory
chmod -R 777 /memory

You'll need to take care of a lot of things :

  • file access (to avoid concurrency between your webapp and your processes)
  • time (to avoid zombies or useless long-running scripts)
  • security (such operations must be carefully designed)
  • resources management (to avoid that 10000 processes runs simuntaneouly)
  • ...



我认为你要找的是 proc_open()命令。 它使您可以访问后台进程的stdin / stdout流。 您可以将自己的stdin / stdout流传递给 $ descriptorSpec </ em>参数中的新进程,这将让您的后台进程与用户通信。</ p>

您的' 前景'应用程序必须等待,直到后台进程死亡。 我还没有用PHP完成这个,但我猜你必须看 $ pipes </ em>来看看它们什么时候关闭 - 那么你就会知道后台进程已经完成了 您可以删除进程资源并继续处理前台进程需要执行的任何操作。</ p>
</ div>

展开原文

原文

I think what you're looking for is the proc_open() command. It gives you access to the stdin/stdout streams of the background process. You can pass your own stdin/stdout streams to the new process in the $descriptorSpec parameter, which will let your background process talk to the user.

Your 'foreground' application will have to wait around until the background process has died. I haven't actuallly done this with PHP, but I'm guessing you'll have to watch the $pipes to see when they get closed -- then you'll know the background process is finished and you can delete the process resource and continue on with whatever the foreground process needs to do.



最后,我设法通过添加第三个引号类型来实现它:`(我相信它被称为'' tack'?)允许我从第一个脚本将参数传递给下一个脚本</ p>

我在php脚本中需要的命令是:</ p>

   $ command =gnome-terminal -e'bash -c“expect~ / commands / login_script.tcl \”$ user \“\”$ host \“\”$ port \“\”$ password \“;  exec bash“'&amp;; 
shell_exec($ command);
</ code> </ pre>

需要一段时间才能获得所有引号,因为交换引号类型可以 导致它无法正常工作。</ p>

这是视频演示最终结果 </ p>
</ div>

展开原文

原文

In the end, I managed to get it working by by adding a third quotation mark type: ` (I believe it is called a 'tack'?) which allowed me to pass arguments to the next script from the first script

The command I needed in my php script was:

$command = `gnome-terminal -e 'bash -c "expect ~/commands/login_script.tcl \"$user\" \"$host\" \"$port\" \"$password\"; exec bash"' &`;
shell_exec($command);

It took a while to get all the quotes right as swapping the type of quotes around can lead to it not working.

Here is a video demonstrating the end result



使用:</ p>

  pcntl_exec(“command”,array(“parameter1”,  “parameter2”)); 
</ code> </ pre>

例如,我有一个脚本使用当前php项目中的参数启动mysql命令,如下所示:</ p >

  pcntl_exec(“/ usr / bin / mysql”,array(
“--user =”。$ params ['user'],
“--password =”。 $ params ['password'],
“--host =”。$ params ['host'],
$ params ['dbname']
));
</ code> </ pre> \ n

这不依赖于gnome终端或任何东西,它将PHP替换为您调用的程序。</ p>

您需要知道命令的完整路径, 是一个痛苦,因为它可能因平台而异,但您可以使用 / usr / bin / env </ code>上的 env </ code>命令命令在大多数系统上查找命令 您。 上面的例子变为:</ p>

  pcntl_exec(“/ usr / bin / env”,array(
“mysql”,
“--user =”。$ params ['user'],
“--password =”。$ params ['password'],
“--host =”。$ params ['host'],
$ params ['dbname'] \ n));
</ code> </ pre>
</ div>

展开原文

原文

Use:

pcntl_exec("command", array("parameter1", "parameter2"));

For example, I have a script that starts the mysql command using the parameters in the current php project that looks like:

pcntl_exec("/usr/bin/mysql", array(
    "--user=".$params['user'],
    "--password=".$params['password'],
    "--host=".$params['host'],
    $params['dbname']
));

This doesn't rely on gnome terminal or anything, it replaces PHP with the program you call.

You do need to know the full path of the command, which is a pain because it can vary by platform, but you can use the env command command which is available at /usr/bin/env on most systems to find the command for you. The above example above becomes:

pcntl_exec("/usr/bin/env", array(
    "mysql",
    "--user=".$params['user'],
    "--password=".$params['password'],
    "--host=".$params['host'],
    $params['dbname']
));

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐