8000 [Process] document command-as-arrays · symfony/symfony-docs@80aa41d · GitHub
[go: up one dir, main page]

Skip to content

Commit 80aa41d

Browse files
[Process] document command-as-arrays
1 parent c90f20a commit 80aa41d

File tree

1 file changed

+44
-67
lines changed

1 file changed

+44
-67
lines changed

components/process.rst

Lines changed: 44 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -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
5555
foreach construct to get the output while it is generated. By default, the loop waits
5656
for 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) deals with 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+
103130
Getting 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
129156
to 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
141168
You can also wait for a process to end if you started it asynchronously and
142169
are 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::
180207
a callback that is called repeatedly whilst the process is still running, passing
181208
in 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
199226
of the constructor. The provided input can be a string, a stream resource or a
200227
Traversable 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
264291
Please read the :ref:`signal documentation below<reference-process-signal>`
265292
to 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-
320315
Process 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-
391377
Process 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-
410390
Disabling 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

0 commit comments

Comments
 (0)
0