@@ -27,7 +27,7 @@ a command in a sub-process::
2727 use Symfony\Component\Process\Process;
2828 use Symfony\Component\Process\Exception\ProcessFailedException;
2929
30- $process = new Process('ls -lsa');
30+ $process = new Process([ 'ls', ' -lsa'] );
3131 $process->run();
3232
3333 // executes after the command finishes
@@ -55,7 +55,7 @@ You can also use the :class:`Symfony\\Component\\Process\\Process` class with th
5555foreach construct to get the output while it is generated. By default, the loop waits
5656for new output before going to the next iteration::
5757
58- $process = new Process('ls -lsa');
58+ $process = new Process([ 'ls', ' -lsa'] );
5959 $process->start();
6060
6161 foreach ($process as $type => $data) {
@@ -72,7 +72,7 @@ for new output before going to the next iteration::
7272 it is generated. That iterator is exposed via the ``getIterator() `` method
7373 to allow customizing its behavior::
7474
75- $process = new Process('ls -lsa');
75+ $process = new Process([ 'ls', ' -lsa'] );
7676 $process->start();
7777 $iterator = $process->getIterator($process::ITER_SKIP_ERR | $process::ITER_KEEP_OUTPUT);
7878 foreach ($iterator as $data) {
@@ -90,7 +90,7 @@ with a non-zero code)::
9090 use Symfony\Component\Process\Exception\ProcessFailedException;
9191 use Symfony\Component\Process\Process;
9292
93- $process = new Process('ls -lsa');
93+ $process = new Process([ 'ls', ' -lsa'] );
9494
9595 try {
9696 $process->mustRun();
@@ -100,6 +100,33 @@ with a non-zero code)::
100100 echo $exception->getMessage();
101101 }
102102
103+ ..tip ::
104+
105+ ..versionadded ::3.3
106+ The ability to define commands as array of arguments was introduced in Symfony 3.3.
107+
108+ When defining commands as arrays, its arguments are escaped for you and you should not
109+ escape them any further. You can also define commands as strings. When doing so, the
110+ command-line is parsed by the underlying shell of your operating system. This allows
111+ using e.g. stream redirections or conditional execution, but this is a lot less portable
112+ since each OS (esp. Windows vs Unix-like) handles escaping and parsing differently.
113+ When passing a command-line string, it becomes your responsibility to deal with this.
114+
115+ Using array of arguments is the recommended way to define commands.
116+
117+ If you need to define commands as strings, variable arguments should be passed as
118+ environment variables using the second argument of the ``run() ``, ``mustRun() `` or
119+ ``start() `` methods. Referencing them in command-line strings is OS-dependent::
120+
121+ // On Unix-like OSes
122+ $process = new Process('echo "$MESSAGE"');
123+
124+ // On Windows
125+ $process = new Process('echo %MESSAGE%');
126+
127+ // On both Unix-like and Windows
128+ $process->run(null, ['MESSAGE' => 'Something to output']);
129+
103130Getting real-time Process Output
104131--------------------------------
105132
@@ -110,7 +137,7 @@ anonymous function to the
110137
111138 use Symfony\Component\Process\Process;
112139
113- $process = new Process('ls -lsa');
140+ $process = new Process([ 'ls', ' -lsa'] );
114141 $process->run(function ($type, $buffer) {
115142 if (Process::ERR === $type) {
116143 echo 'ERR > '.$buffer;
@@ -129,7 +156,7 @@ process, the :method:`Symfony\\Component\\Process\\Process::isRunning` method
129156to check if the process is done and the
130157:method: `Symfony\\ Component\\ Process\\ Process::getOutput ` method to get the output::
131158
132- $process = new Process('ls -lsa');
159+ $process = new Process([ 'ls', ' -lsa'] );
133160 $process->start();
134161
135162 while ($process->isRunning()) {
@@ -141,7 +168,7 @@ to check if the process is done and the
141168You can also wait for a process to end if you started it asynchronously and
142169are done doing other stuff::
143170
144- $process = new Process('ls -lsa');
171+ $process = new Process([ 'ls', ' -lsa'] );
145172 $process->start();
146173
147174 // ... do other things
@@ -180,7 +207,7 @@ are done doing other stuff::
180207a callback that is called repeatedly whilst the process is still running, passing
181208in the output and its type::
182209
183- $process = new Process('ls -lsa');
210+ $process = new Process([ 'ls', ' -lsa'] );
184211 $process->start();
185212
186213 $process->wait(function ($type, $buffer) {
@@ -199,7 +226,7 @@ Before a process is started, you can specify its standard input using either the
199226of the constructor. The provided input can be a string, a stream resource or a
200227Traversable object::
201228
202- $process = new Process('cat');
229+ $process = new Process([ 'cat'] );
203230 $process->setInput('foobar');
204231 $process->run();
205232
@@ -212,7 +239,7 @@ provides the :class:`Symfony\\Component\\Process\\InputStream` class::
212239 $input = new InputStream();
213240 $input->write('foo');
214241
215- $process = new Process('cat');
242+ $process = new Process([ 'cat'] );
216243 $process->setInput($input);
217244 $process->start();
218245
@@ -238,7 +265,7 @@ The input of a process can also be defined using `PHP streams`_::
238265
239266 $stream = fopen('php://temporary', 'w+');
240267
241- $process = new Process('cat');
268+ $process = new Process([ 'cat'] );
242269 $process->setInput($stream);
243270 $process->start();
244271
@@ -264,7 +291,7 @@ is sent to the running process. The default signal sent to a process is ``SIGKIL
264291Please read the:ref: `signal documentation below<reference-process-signal> `
265292to find out more about signal handling in the Process component::
266293
267- $process = new Process('ls -lsa');
294+ $process = new Process([ 'ls', ' -lsa'] );
268295 $process->start();
269296
270297 // ... do other things
@@ -285,38 +312,6 @@ instead::
285312 );
286313 $process->run();
287314
288- To make your code work better on all platforms, you might want to use the
289- :class: `Symfony\\ Component\\ Process\\ ProcessBuilder ` class instead::
290-
291- use Symfony\Component\Process\ProcessBuilder;
292-
293- $processBuilder = new ProcessBuilder(array('ls', '-lsa'));
294- $processBuilder->getProcess()->run();
295-
296- In case you are building a binary driver, you can use the
297- :method: `Symfony\\ Component\\ Process\\ ProcessBuilder::setPrefix ` method to prefix all
298- the generated process commands.
299-
300- The following example will generate two process commands for a tar binary
301- adapter::
302-
303- use Symfony\Component\Process\ProcessBuilder;
304-
305- $processBuilder = new ProcessBuilder();
306- $processBuilder->setPrefix('/usr/bin/tar');
307-
308- // '/usr/bin/tar' '--list' '--file=archive.tar.gz'
309- echo $processBuilder
310- ->setArguments(array('--list', '--file=archive.tar.gz'))
311- ->getProcess()
312- ->getCommandLine();
313-
314- // '/usr/bin/tar' '-xzf' 'archive.tar.gz'
315- echo $processBuilder
316- ->setArguments(array('-xzf', 'archive.tar.gz'))
317- ->getProcess()
318- ->getCommandLine();
319-
320315Process Timeout
321316---------------
322317
@@ -325,7 +320,7 @@ timeout (in seconds)::
325320
326321 use Symfony\Component\Process\Process;
327322
328- $process = new Process('ls -lsa');
323+ $process = new Process([ 'ls', ' -lsa'] );
329324 $process->setTimeout(3600);
330325 $process->run();
331326
@@ -357,7 +352,7 @@ considers the time since the last output was produced by the process::
357352
358353 use Symfony\Component\Process\Process;
359354
360- $process = new Process('something-with-variable-runtime');
355+ $process = new Process([ 'something-with-variable-runtime'] );
361356 $process->setTimeout(3600);
362357 $process->setIdleTimeout(60);
363358 $process->run();
@@ -373,21 +368,12 @@ When running a program asynchronously, you can send it POSIX signals with the
373368
374369 use Symfony\Component\Process\Process;
375370
376- $process = new Process('find / -name " rabbit"' );
371+ $process = new Process([ 'find', '/', ' -name', ' rabbit'] );
377372 $process->start();
378373
379374 // will send a SIGKILL to the process
380375 $process->signal(SIGKILL);
381376
382- ..caution ::
383-
384- Due to some limitations in PHP, if you're using signals with the Process
385- component, you may have to prefix your commands with `exec `_. Please read
386- `Symfony Issue#5759 `_ and `PHP Bug#39992 `_ to understand why this is happening.
387-
388- POSIX signals are not available on Windows platforms, please refer to the
389- `PHP documentation `_ for available signals.
390-
391377Process Pid
392378-----------
393379
@@ -396,17 +382,11 @@ You can access the `pid`_ of a running process with the
396382
397383 use Symfony\Component\Process\Process;
398384
399- $process = new Process('/usr/bin/php worker.php');
385+ $process = new Process([ '/usr/bin/php', ' worker.php'] );
400386 $process->start();
401387
402388 $pid = $process->getPid();
403389
404- ..caution ::
405-
406- Due to some limitations in PHP, if you want to get the pid of a symfony Process,
407- you may have to prefix your commands with `exec `_. Please read
408- `Symfony Issue#5759 `_ to understand why this is happening.
409-
410390Disabling Output
411391----------------
412392
@@ -417,7 +397,7 @@ Use :method:`Symfony\\Component\\Process\\Process::disableOutput` and
417397
418398 use Symfony\Component\Process\Process;
419399
420- $process = new Process('/usr/bin/php worker.php');
400+ $process = new Process([ '/usr/bin/php', ' worker.php'] );
421401 $process->disableOutput();
422402 $process->run();
423403
@@ -449,9 +429,6 @@ absolute path of the executable PHP binary available on your server::
449429 $phpBinaryPath = $phpBinaryFinder->find();
450430 // $phpBinaryPath = '/usr/local/bin/php' (the result will be different on your computer)
451431
452- .. _`Symfony Issue#5759` :https://github.com/symfony/symfony/issues/5759
453- .. _`PHP Bug#39992` :https://bugs.php.net/bug.php?id=39992
454- .. _`exec` :https://en.wikipedia.org/wiki/Exec_(operating_system)
455432.. _`pid` :https://en.wikipedia.org/wiki/Process_identifier
456433.. _`PHP Documentation` :https://php.net/manual/en/pcntl.constants.php
457434.. _Packagist :https://packagist.org/packages/symfony/process