8000 [Process] document command-as-arrays by nicolas-grekas · Pull Request #9988 · symfony/symfony-docs · GitHub
[go: up one dir, main page]

Skip to content

[Process] document command-as-arrays #9988

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 4, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 49 additions & 67 deletions components/process.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ a command in a sub-process::
use Symfony\Component\Process\Process;
use Symfony\Component\Process\Exception\ProcessFailedException;

$process = new Process('ls -lsa');
$process = new Process(array('ls', '-lsa'));
$process->run();

// executes after the command finishes
Expand Down Expand Up @@ -55,7 +55,7 @@ You can also use the :class:`Symfony\\Component\\Process\\Process` class with th
foreach construct to get the output while it is generated. By default, the loop waits
for new output before going to the next iteration::

$process = new Process('ls -lsa');
$process = new Process(array('ls', '-lsa'));
$process->start();

foreach ($process as $type => $data) {
Expand All @@ -72,7 +72,7 @@ for new output before going to the next iteration::
it is generated. That iterator is exposed via the ``getIterator()`` method
to allow customizing its behavior::

$process = new Process('ls -lsa');
$process = new Process(array('ls', '-lsa'));
$process->start();
$iterator = $process->getIterator($process::ITER_SKIP_ERR | $process::ITER_KEEP_OUTPUT);
foreach ($iterator as $data) {
Expand All @@ -90,7 +90,7 @@ with a non-zero code)::
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;

$process = new Process('ls -lsa');
$process = new Process(array('ls', '-lsa'));

try {
$process->mustRun();
Expand All @@ -100,6 +100,38 @@ with a non-zero code)::
echo $exception->getMessage();
}

.. tip::

.. versionadded:: 3.3
The ability to define commands as arrays of arguments was introduced in
Symfony 3.3.

Using array of arguments is the recommended way to define commands. This
saves you from any escaping and allows sending signals seamlessly
(e.g. to stop processes before completion.)::

$process = new Process(array('/path/command', '--flag', 'arg 1', 'etc.'));

If you need use stream redirections, conditional execution, or any other
C 8000 opy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to use

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, fixed in 2c5579b

features provided by the shell of your operating system, you can also define
commands as strings.

Please note that each OS provides a different syntax for their command-lines
so that it becomes your responsibility to deal with escaping and portability.

To provide any variable arguments to command-line string, pass them as
environment variables using the second argument of the ``run()``,
``mustRun()`` or ``start()`` methods. Referencing them is also OS-dependent::

// On Unix-like OSes (Linux, macOS)
$process = new Process('echo "$MESSAGE"');

// On Windows
$process = new Process('echo "!MESSAGE!"');

// On both Unix-like and Windows
$process->run(null, array('MESSAGE' => 'Something to output'));

Getting real-time Process Output
--------------------------------

Expand All @@ -110,7 +142,7 @@ anonymous function to the

use Symfony\Component\Process\Process;

$process = new Process('ls -lsa');
$process = new Process(array('ls', '-lsa'));
$process->run(function ($type, $buffer) {
if (Process::ERR === $type) {
echo 'ERR > '.$buffer;
Expand All @@ -129,7 +161,7 @@ process, the :method:`Symfony\\Component\\Process\\Process::isRunning` method
to check if the process is done and the
:method:`Symfony\\Component\\Process\\Process::getOutput` method to get the output::

$process = new Process('ls -lsa');
$process = new Process(array('ls', '-lsa'));
$process->start();

while ($process->isRunning()) {
Expand All @@ -141,7 +173,7 @@ to check if the process is done and the
You can also wait for a process to end if you started it asynchronously and
are done doing other stuff::

$process = new Process('ls -lsa');
$process = new Process(array('ls', '-lsa'));
$process->start();

// ... do other things
Expand Down Expand Up @@ -180,7 +212,7 @@ are done doing other stuff::
a callback that is called repeatedly whilst the process is still running, passing
in the output and its type::

$process = new Process('ls -lsa');
$process = new Process(array('ls', '-lsa'));
$process->start();

$process->wait(function ($type, $buffer) {
Expand All @@ -199,7 +231,7 @@ Before a process is started, you can specify its standard input using either the
of the constructor. The provided input can be a string, a stream resource or a
Traversable object::

$process = new Process('cat');
$process = new Process('cat']);
$process->setInput('foobar');
$process->run();

Expand All @@ -212,7 +244,7 @@ provides the :class:`Symfony\\Component\\Process\\InputStream` class::
$input = new InputStream();
$input->write('foo');

$process = new Process('cat');
$process = new Process(array('cat'));
$process->setInput($input);
$process->start();

Expand All @@ -238,7 +270,7 @@ The input of a process can also be defined using `PHP streams`_::

$stream = fopen('php://temporary', 'w+');

$process = new Process('cat');
$process = new Process(array('cat'));
$process->setInput($stream);
$process->start();

Expand All @@ -264,7 +296,7 @@ is sent to the running process. The default signal sent to a process is ``SIGKIL
Please read the :ref:`signal documentation below<reference-process-signal>`
to find out more about signal handling in the Process component::

$process = new Process('ls -lsa');
$process = new Process(array('ls', '-lsa'));
$process->start();

// ... do other things
Expand All @@ -285,38 +317,6 @@ instead::
);
$process->run();

To make your code work better on all platforms, you might want to use the
:class:`Symfony\\Component\\Process\\ProcessBuilder` class instead::

use Symfony\Component\Process\ProcessBuilder;

$processBuilder = new ProcessBuilder(array('ls', '-lsa'));
$processBuilder->getProcess()->run();

In case you are building a binary driver, you can use the
:method:`Symfony\\Component\\Process\\ProcessBuilder::setPrefix` method to prefix all
the generated process commands.

The following example will generate two process commands for a tar binary
adapter::

use Symfony\Component\Process\ProcessBuilder;

$processBuilder = new ProcessBuilder();
$processBuilder->setPrefix('/usr/bin/tar');

// '/usr/bin/tar' '--list' '--file=archive.tar.gz'
echo $processBuilder
->setArguments(array('--list', '--file=archive.tar.gz'))
->getProcess()
->getCommandLine();

// '/usr/bin/tar' '-xzf' 'archive.tar.gz'
echo $processBuilder
->setArguments(array('-xzf', 'archive.tar.gz'))
->getProcess()
->getCommandLine();

Process Timeout
---------------

Expand All @@ -325,7 +325,7 @@ timeout (in seconds)::

use Symfony\Component\Process\Process;

$process = new Process('ls -lsa');
$process = new Process(array('ls', '-lsa'));
$process->setTimeout(3600);
$process->run();

Expand Down Expand Up @@ -357,7 +357,7 @@ considers the time since the last output was produced by the process::

use Symfony\Component\Process\Process;

$process = new Process('something-with-variable-runtime');
$process = new Process(array('something-with-variable-runtime'));
$process->setTimeout(3600);
$process->setIdleTimeout(60);
$process->run();
Expand All @@ -373,21 +373,12 @@ When running a program asynchronously, you can send it POSIX signals with the

use Symfony\Component\Process\Process;

$process = new Process('find / -name "rabbit"');
$process = new Process(array('find', '/', '-name', 'rabbit'));
$process->start();

// will send a SIGKILL to the process
$process->signal(SIGKILL);

.. caution::

Due to some limitations in PHP, if you're using signals with the Process
component, you may have to prefix your commands with `exec`_. Please read
`Symfony Issue#5759`_ and `PHP Bug#39992`_ to understand why this is happening.

POSIX signals are not available on Windows platforms, please refer to the
`PHP documentation`_ for available signals.

Process Pid
-----------

Expand All @@ -396,17 +387,11 @@ You can access the `pid`_ of a running process with the

use Symfony\Component\Process\Process;

$process = new Process('/usr/bin/php worker.php');
$process = new Process(array('/usr/bin/php', 'worker.php'));
$process->start();

$pid = $process->getPid();

.. caution::

Due to some limitations in PHP, if you want to get the pid of a symfony Process,
you may have to prefix your commands with `exec`_. Please read
`Symfony Issue#5759`_ to understand why this is happening.

Disabling Output
----------------

Expand All @@ -417,7 +402,7 @@ Use :method:`Symfony\\Component\\Process\\Process::disableOutput` and

use Symfony\Component\Process\Process;

$process = new Process('/usr/bin/php worker.php');
$process = new Process(array('/usr/bin/php', 'worker.php'));
$process->disableOutput();
$process->run();

Expand Down Expand Up @@ -449,9 +434,6 @@ absolute path of the executable PHP binary available on your server::
$phpBinaryPath = $phpBinaryFinder->find();
// $phpBinaryPath = '/usr/local/bin/php' (the result will be different on your computer)

.. _`Symfony Issue#5759`: https://github.com/symfony/symfony/issues/5759
.. _`PHP Bug#39992`: https://bugs.php.net/bug.php?id=39992
.. _`exec`: https://en.wikipedia.org/wiki/Exec_(operating_system)
.. _`pid`: https://en.wikipedia.org/wiki/Process_identifier
.. _`PHP Documentation`: https://php.net/manual/en/pcntl.constants.php
.. _Packagist: https://packagist.org/packages/symfony/process
Expand Down
0