ℹ️ Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://symfony.com/doc/current/components/process.html |
| Last Crawled | 2026-04-06 16:01:42 (9 hours ago) |
| First Indexed | 2015-06-16 03:38:45 (10 years ago) |
| HTTP Status Code | 200 |
| Meta Title | The Process Component (Symfony Docs) |
| Meta Description | The Process component executes commands in sub-processes. Installation 1 $ composer require symfony/process Note If you… |
| Meta Canonical | null |
| Boilerpipe Text | The Process component executes commands in sub-processes.
Installation
Note
If you install this component outside of a Symfony application, you must
require the
vendor/autoload.php
file in your code to enable the class
autoloading mechanism provided by Composer. Read
this article
for more details.
Usage
The
Process
class executes a command in a
sub-process, taking care of the differences between operating system and
escaping arguments to prevent security issues. It replaces PHP functions like
exec
,
passthru
,
shell_exec
and
system
:
The
getOutput()
method always returns the whole content of the standard
output of the command and
getErrorOutput()
the content of the error
output. Alternatively, the
getIncrementalOutput()
and
getIncrementalErrorOutput()
methods return the new output since the last call.
The
clearOutput()
method clears
the contents of the output and
clearErrorOutput()
clears
the contents of the error output.
You can also use the
Process
class with the
for each construct to get the output while it is generated. By default, the loop waits
for new output before going to the next iteration:
Tip
The Process component internally uses a PHP iterator to get the output while
it is generated. That iterator is exposed via the
getIterator()
method
to allow customizing its behavior:
The
mustRun()
method is identical to
run()
, except that it will throw
a
ProcessFailedException
if the process couldn't be executed successfully (i.e. the process exited
with a non-zero code):
Tip
You can get the last output time in seconds by using the
getLastOutputTime()
method.
This method returns
null
if the process wasn't started!
Configuring Process Options
Symfony uses the PHP
proc_open
function to run the processes.
You can configure the options passed to the
other_options
argument of
proc_open()
using the
setOptions()
method:
Warning
Most of the options defined by
proc_open()
(such as
create_new_console
and
suppress_errors
) are only supported on Windows operating systems.
Check out the
PHP documentation for proc_open()
before using them.
Using Features From the OS Shell
Using an 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 while they run):
If you need to use stream redirections, conditional execution, or any other
feature provided by the shell of your operating system, you can also define
commands as strings using the
fromShellCommandline()
static
factory.
Each operating system provides a different syntax for their command-lines,
so it becomes your responsibility to deal with escaping and portability.
When using strings to define commands, variable arguments are passed as
environment variables using the second argument of the
run()
,
mustRun()
or
start()
methods. Referencing them is also OS-dependent:
If you prefer to create portable commands that are independent from the
operating system, you can write the above command as follows:
Portable commands require using a syntax that is specific to the component: when
enclosing a variable name into
"${:
and
}"
exactly, the process object
will replace it with its escaped value, or will fail if the variable is not
found in the list of environment variables attached to the command.
Setting Environment Variables for Processes
The constructor of the
Process
class and
all of its methods related to executing processes (
run()
,
mustRun()
,
start()
, etc.) allow passing an array of environment variables to set while
running the process:
In addition to the env vars passed explicitly, processes inherit all the env
vars defined in your system. You can prevent this by setting the env vars you want
to remove to
false
:
Getting real-time Process Output
When executing a long running command (like
rsync
to a remote
server), you can give feedback to the end user in real-time by passing an
anonymous function to the
run()
method:
Note
This feature won't work as expected in servers using PHP output buffering.
In those cases, either disable the
output_buffering
PHP option or use the
ob_flush
PHP function to force sending the output buffer.
Running Processes Asynchronously
You can also start the subprocess and then let it run asynchronously, retrieving
output and the status in your main process whenever you need it. Use the
start()
method to start an asynchronous
process, the
isRunning()
method
to check if the process is done and the
getOutput()
method to get the output:
You can also wait for a process to end if you started it asynchronously and
are done doing other stuff:
Note
The
wait()
method is blocking,
which means that your code will halt at this line until the external
process is completed.
Note
If a
Response
is sent
before
a child process had a chance to complete,
the server process will be killed (depending on your OS). It means that
your task will be stopped right away. Running an asynchronous process
is not the same as running a process that survives its parent process.
If you want your process to survive the request/response cycle, you can
take advantage of the
kernel.terminate
event, and run your command
synchronously
inside this event. Be aware that
kernel.terminate
is called only if you use PHP-FPM.
Danger
Beware also that if you do that, the said PHP-FPM process will not be
available to serve any new request until the subprocess is finished. This
means you can quickly block your FPM pool if you're not careful enough.
That is why it's generally way better not to do any fancy things even
after the request is sent, but to use a job queue instead.
wait()
takes one optional argument:
a callback that is called repeatedly while the process is still running, passing
in the output and its type:
Instead of waiting until the process has finished, you can use the
waitUntil()
method to keep or stop
waiting based on some PHP logic. The following example starts a long running
process and checks its output to wait until its fully initialized:
Streaming to the Standard Input of a Process
Before a process is started, you can specify its standard input using either the
setInput()
method or the 4th argument
of the constructor. The provided input can be a string, a stream resource or a
Traversable
object:
When this input is fully written to the subprocess standard input, the corresponding
pipe is closed.
In order to write to a subprocess standard input while it is running, the component
provides the
InputStream
class:
The
write()
method accepts scalars,
stream resources or
Traversable
objects as arguments. As shown in the above example,
you need to explicitly call the
close()
method when you are done writing to the standard input of the subprocess.
Using TTY and PTY Modes
All examples above show that your program has control over the input of a
process (using
setInput()
) and the output from that process (using
getOutput()
). The Process component has two special modes that tweak
the relationship between your program and the process: teletype (tty) and
pseudo-teletype (pty).
In TTY mode, you connect the input and output of the process to the input
and output of your program. This allows for instance to open an editor like
Vim or Nano as a process. You enable TTY mode by calling
setTty()
:
In PTY mode, your program behaves as a terminal for the process instead of
a plain input and output. Some programs behave differently when
interacting with a real terminal instead of another program. For instance,
some programs prompt for a password when talking with a terminal. Use
setPty()
to enable this
mode.
Stopping a Process
Any asynchronous process can be stopped at any time with the
stop()
method. This method takes
two arguments: a timeout and a signal. Once the timeout is reached, the signal
is sent to the running process. The default signal sent to a process is
SIGKILL
.
Please read the
signal documentation below
to find out more about signal handling in the Process component:
Executing PHP Code in Isolation
If you want to execute some PHP code in isolation, use the
PhpProcess
instead:
Executing a PHP Child Process with the Same Configuration
When you start a PHP process, it uses the default configuration defined in
your
php.ini
file. You can bypass these options with the
-d
command line
option. For example, if
memory_limit
is set to
256M
, you can disable this
memory limit when running some command like this:
php -d memory_limit=-1 bin/console app:my-command
.
However, if you run the command via the Symfony
Process
class, PHP will use
the settings defined in the
php.ini
file. You can solve this issue by using
the
PhpSubprocess
class to run the command:
Process Timeout
By default processes have a timeout of 60 seconds, but you can change it passing
a different timeout (in seconds) to the
setTimeout()
method:
If the timeout is reached, a
ProcessTimedOutException
is thrown.
For long running commands, it is your responsibility to perform the timeout
check regularly:
Tip
You can get the process start time using the
getStartTime()
method.
Process Idle Timeout
In contrast to the timeout of the previous paragraph, the idle timeout only
considers the time since the last output was produced by the process:
In the case above, a process is considered timed out, when either the total runtime
exceeds 3600 seconds, or the process does not produce any output for 60 seconds.
Process Signals
When running a program asynchronously, you can send it POSIX signals with the
signal()
method:
You can make the process ignore signals by using the
setIgnoredSignals()
method. The given signals won't be propagated to the child process:
Process Pid
You can access the
pid
of a running process with the
getPid()
method:
Disabling Output
As standard output and error output are always fetched from the underlying process,
it might be convenient to disable output in some cases to save memory.
Use
disableOutput()
and
enableOutput()
to toggle this feature:
Warning
You cannot enable or disable the output while the process is running.
If you disable the output, you cannot access
getOutput()
,
getIncrementalOutput()
,
getErrorOutput()
,
getIncrementalErrorOutput()
or
setIdleTimeout()
.
However, it is possible to pass a callback to the
start
,
run
or
mustRun
methods to handle process output in a streaming fashion.
Finding an Executable
The Process component provides a utility class called
ExecutableFinder
which finds
and returns the absolute path of an executable:
The
find()
method also takes extra parameters to specify a default value
to return and extra directories where to look for the executable:
Finding the Executable PHP Binary
This component also provides a special utility class called
PhpExecutableFinder
which returns the
absolute path of the executable PHP binary available on your server:
Checking for TTY Support
Another utility provided by this component is a method called
isTtySupported()
which returns
whether
TTY
is supported on the current operating system:
This work, including the code samples, is licensed under a
Creative Commons BY-SA 3.0
license. |
| Markdown | [Skip to content](https://symfony.com/doc/current/components/process.html#main-content)
[SymfonyHub](https://symfony.com/doc/current/components/process.html "Toggle Symfony menu") [SFH](https://symfony.com/doc/current/components/process.html "Toggle Symfony menu")
[ Blackfire.io](https://www.blackfire.io/?utm_source=symfony&utm_medium=banner&utm_campaign=profiler) [ Blackfire.io: Fire up your PHP apps performance](https://www.blackfire.io/?utm_source=symfony&utm_medium=banner&utm_campaign=profiler) [ Blackfire.io: Fire up your PHP apps performance](https://www.blackfire.io/?utm_source=symfony&utm_medium=banner&utm_campaign=profiler)
[Connect](https://symfony.com/connect/login?target=https://symfony.com/doc/current/components/process.html)

SensioLabs is the creator of Symfony and plays a pivotal role in supporting its growth. With a passionate team pushing the boundaries of PHP, SensioLabs helps organizations get the most out of Symfony through quality, high-performance, software vendor-level training and consulting services.
- [International](https://sensiolabs.com/en)
- [France](https://sensiolabs.com/fr)
## In the Spotlight
[](https://insight.symfony.com/)
[](https://www.blackfire.io/?utm_source=symfony&utm_medium=banner&utm_campaign=profiler)
## Open Source
- [Symfony - Web framework](https://symfony.com/)
- [Twig - Templating](https://twig.symfony.com/)
- [PHP Polyfills](https://github.com/symfony/polyfill)
## Products
- [Insight: PHP Quality](https://insight.symfony.com/)
- [Blackfire: Web App performance](https://www.blackfire.io/?utm_source=symfony&utm_medium=banner&utm_campaign=profiler)
- [SymfonyCloud powered by Upsun](https://symfony.com/cloud)
## Solutions & Services
- [Training](https://training.sensiolabs.com/)
- [Certification](https://certification.symfony.com/)
- [Technical Solutions](https://sensiolabs.com/solutions)
- [SensioLabs University](https://university.sensiolabs.com/)
- [Experts](https://expert.sensiolabs.com/)
## Community
- [Community](https://connect.symfony.com/)
- [Conferences](https://live.symfony.com/)
- [Videos](https://www.youtube.com/symfonytv)
- [Partners](https://network.sensiolabs.com/en/partenaires)
## Blogs
[Symfony](https://symfony.com/blog/), [SensioLabs](https://blog.sensiolabs.com/), [Insight](https://blog.insight.symfony.com/), and [Blackfire](https://blog.blackfire.io/?utm_source=symfony&utm_medium=banner&utm_campaign=profiler).
Close
- About
- [What is Symfony?](https://symfony.com/what-is-symfony)
- [Community](https://symfony.com/community)
- [News](https://symfony.com/blog/)
- [Contributing](https://symfony.com/doc/current/contributing/index.html)
- [Support](https://symfony.com/support)
- Documentation
- [Symfony Docs](https://symfony.com/doc)
- [Symfony Book](https://symfony.com/book)
- [Screencasts](https://symfonycasts.com/)
- [Symfony Bundles](https://symfony.com/bundles)
- [Symfony Cloud](https://symfony.com/doc/cloud/)
- [Training](https://sensiolabs.com/training?utm_source=symfony&utm_medium=symfony_submenu&utm_campaign=permanent_referral)
- Services
- [Upsun for Symfony](https://symfony.com/cloud/) Best platform to deploy Symfony apps
- [SymfonyInsight](https://insight.symfony.com/) Automatic quality checks for your apps
- [Symfony Certification](https://certification.symfony.com/) Prove your knowledge and boost your career
- [SensioLabs](https://sensiolabs.com/?utm_source=symfony&utm_medium=symfony_submenu&utm_campaign=permanent_referral) Professional services to help you with Symfony
- [Blackfire](https://www.blackfire.io/?utm_source=symfony&utm_medium=symfonycom_footer&utm_campaign=profiler) Profile and monitor performance of your apps
- Other
- [Blog](https://symfony.com/blog/)
- [Download](https://symfony.com/download)
sponsored by
[SymfonyDay Montreal 2026](https://live.symfony.com/2026-montreal)
June 4, 2026
\+20 talks and workshops
Register now
1. [Home](https://symfony.com/)
2. [Documentation](https://symfony.com/doc)
3. [Components](https://symfony.com/doc/current/components/index.html)
4. The Process Component
Search Symfony Docs
Version:
Table of Contents
- [Installation](https://symfony.com/doc/current/components/process.html#installation)
- [Usage](https://symfony.com/doc/current/components/process.html#usage)
- [Configuring Process Options](https://symfony.com/doc/current/components/process.html#configuring-process-options)
- [Using Features From the OS Shell](https://symfony.com/doc/current/components/process.html#using-features-from-the-os-shell)
- [Setting Environment Variables for Processes](https://symfony.com/doc/current/components/process.html#setting-environment-variables-for-processes)
- [Getting real-time Process Output](https://symfony.com/doc/current/components/process.html#getting-real-time-process-output)
- [Running Processes Asynchronously](https://symfony.com/doc/current/components/process.html#running-processes-asynchronously)
- [Streaming to the Standard Input of a Process](https://symfony.com/doc/current/components/process.html#streaming-to-the-standard-input-of-a-process)
- [Using PHP Streams as the Standard Input of a Process](https://symfony.com/doc/current/components/process.html#using-php-streams-as-the-standard-input-of-a-process)
- [Using TTY and PTY Modes](https://symfony.com/doc/current/components/process.html#using-tty-and-pty-modes)
- [Stopping a Process](https://symfony.com/doc/current/components/process.html#stopping-a-process)
- [Executing PHP Code in Isolation](https://symfony.com/doc/current/components/process.html#executing-php-code-in-isolation)
- [Executing a PHP Child Process with the Same Configuration](https://symfony.com/doc/current/components/process.html#executing-a-php-child-process-with-the-same-configuration)
- [Process Timeout](https://symfony.com/doc/current/components/process.html#process-timeout)
- [Process Idle Timeout](https://symfony.com/doc/current/components/process.html#process-idle-timeout)
- [Process Signals](https://symfony.com/doc/current/components/process.html#process-signals)
- [Process Pid](https://symfony.com/doc/current/components/process.html#process-pid)
- [Disabling Output](https://symfony.com/doc/current/components/process.html#disabling-output)
- [Finding an Executable](https://symfony.com/doc/current/components/process.html#finding-an-executable)
- [Finding the Executable PHP Binary](https://symfony.com/doc/current/components/process.html#finding-the-executable-php-binary)
- [Checking for TTY Support](https://symfony.com/doc/current/components/process.html#checking-for-tty-support)
# The Process Component
[Edit this page](https://github.com/symfony/symfony-docs/edit/8.0/components/process.rst)
> The Process component executes commands in sub-processes.
## [Installation](https://symfony.com/doc/current/components/process.html#installation "Permalink to this headline")
Copy
```
1
```
```
$ composer require symfony/process
```
Note
If you install this component outside of a Symfony application, you must require the `vendor/autoload.php` file in your code to enable the class autoloading mechanism provided by Composer. Read [this article](https://symfony.com/doc/current/components/using_components.html) for more details.
## [Usage](https://symfony.com/doc/current/components/process.html#usage "Permalink to this headline")
The [Process](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php "Symfony\Component\Process\Process") class executes a command in a sub-process, taking care of the differences between operating system and escaping arguments to prevent security issues. It replaces PHP functions like [exec](https://secure.php.net/manual/en/function.exec.php "exec"), [passthru](https://secure.php.net/manual/en/function.passthru.php "passthru"), [shell\_exec](https://secure.php.net/manual/en/function.shell-exec.php "shell_exec") and [system](https://secure.php.net/manual/en/function.system.php "system"):
```
1
2
3
4
5
6
7
8
9
10
11
12
```
```
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;
$process = new Process(['ls', '-lsa']);
$process->run();
// executes after the command finishes
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}
echo $process->getOutput();
```
The `getOutput()` method always returns the whole content of the standard output of the command and `getErrorOutput()` the content of the error output. Alternatively, the [getIncrementalOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getIncrementalOutput "Symfony\Component\Process\Process::getIncrementalOutput()") and [getIncrementalErrorOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getIncrementalErrorOutput "Symfony\Component\Process\Process::getIncrementalErrorOutput()") methods return the new output since the last call.
The [clearOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20clearOutput "Symfony\Component\Process\Process::clearOutput()") method clears the contents of the output and [clearErrorOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20clearErrorOutput "Symfony\Component\Process\Process::clearErrorOutput()") clears the contents of the error output.
You can also use the [Process](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php "Symfony\Component\Process\Process") class with the for each construct to get the output while it is generated. By default, the loop waits for new output before going to the next iteration:
```
1
2
3
4
5
6
7
8
9
10
```
```
$process = new Process(['ls', '-lsa']);
$process->start();
foreach ($process as $type => $data) {
if ($process::OUT === $type) {
echo "\nRead from stdout: ".$data;
} else { // $process::ERR === $type
echo "\nRead from stderr: ".$data;
}
}
```
Tip
The Process component internally uses a PHP iterator to get the output while it is generated. That iterator is exposed via the `getIterator()` method to allow customizing its behavior:
```
1
2
3
4
5
6
```
```
$process = new Process(['ls', '-lsa']);
$process->start();
$iterator = $process->getIterator($process::ITER_SKIP_ERR | $process::ITER_KEEP_OUTPUT);
foreach ($iterator as $data) {
echo $data."\n";
}
```
The `mustRun()` method is identical to `run()`, except that it will throw a [ProcessFailedException](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Exception/ProcessFailedException.php "Symfony\Component\Process\Exception\ProcessFailedException") if the process couldn't be executed successfully (i.e. the process exited with a non-zero code):
```
1
2
3
4
5
6
7
8
9
10
11
12
```
```
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;
$process = new Process(['ls', '-lsa']);
try {
$process->mustRun();
echo $process->getOutput();
} catch (ProcessFailedException $exception) {
echo $exception->getMessage();
}
```
Tip
You can get the last output time in seconds by using the [getLastOutputTime()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getLastOutputTime "Symfony\Component\Process\Process::getLastOutputTime()") method. This method returns `null` if the process wasn't started\!
## [Configuring Process Options](https://symfony.com/doc/current/components/process.html#configuring-process-options "Permalink to this headline")
Symfony uses the PHP [proc\_open](https://secure.php.net/manual/en/function.proc-open.php "proc_open") function to run the processes. You can configure the options passed to the `other_options` argument of `proc_open()` using the `setOptions()` method:
```
1
2
3
```
```
$process = new Process(['...', '...', '...']);
// this option allows a subprocess to continue running after the main script exited
$process->setOptions(['create_new_console' => true]);
```
Warning
Most of the options defined by `proc_open()` (such as `create_new_console` and `suppress_errors`) are only supported on Windows operating systems. Check out the [PHP documentation for proc\_open()](https://www.php.net/manual/en/function.proc-open.php) before using them.
## [Using Features From the OS Shell](https://symfony.com/doc/current/components/process.html#using-features-from-the-os-shell "Permalink to this headline")
Using an 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 while they run):
```
1
2
```
```
$process = new Process(['/path/command', '--option', 'argument', 'etc.']);
$process = new Process(['/path/to/php', '--define', 'memory_limit=1024M', '/path/to/script.php']);
```
If you need to use stream redirections, conditional execution, or any other feature provided by the shell of your operating system, you can also define commands as strings using the [fromShellCommandline()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20fromShellCommandline "Symfony\Component\Process\Process::fromShellCommandline()") static factory.
Each operating system provides a different syntax for their command-lines, so it becomes your responsibility to deal with escaping and portability.
When using strings to define commands, variable arguments are passed as environment variables using the second argument of the `run()`, `mustRun()` or `start()` methods. Referencing them is also OS-dependent:
```
1
2
3
4
5
6
7
8
```
```
// On Unix-like OSes (Linux, macOS)
$process = Process::fromShellCommandline('echo "$MESSAGE"');
// On Windows
$process = Process::fromShellCommandline('echo "!MESSAGE!"');
// On both Unix-like and Windows
$process->run(null, ['MESSAGE' => 'Something to output']);
```
If you prefer to create portable commands that are independent from the operating system, you can write the above command as follows:
```
1
2
```
```
// works the same on Windows , Linux and macOS
$process = Process::fromShellCommandline('echo "${:MESSAGE}"');
```
Portable commands require using a syntax that is specific to the component: when enclosing a variable name into `"${:` and `}"` exactly, the process object will replace it with its escaped value, or will fail if the variable is not found in the list of environment variables attached to the command.
## [Setting Environment Variables for Processes](https://symfony.com/doc/current/components/process.html#setting-environment-variables-for-processes "Permalink to this headline")
The constructor of the [Process](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php "Symfony\Component\Process\Process") class and all of its methods related to executing processes (`run()`, `mustRun()`, `start()`, etc.) allow passing an array of environment variables to set while running the process:
```
1
2
3
```
```
$process = new Process(['...'], null, ['ENV_VAR_NAME' => 'value']);
$process = Process::fromShellCommandline('...', null, ['ENV_VAR_NAME' => 'value']);
$process->run(null, ['ENV_VAR_NAME' => 'value']);
```
In addition to the env vars passed explicitly, processes inherit all the env vars defined in your system. You can prevent this by setting the env vars you want to remove to `false`:
```
1
2
3
4
```
```
$process = new Process(['...'], null, [
'APP_ENV' => false,
'SYMFONY_DOTENV_VARS' => false,
]);
```
## [Getting real-time Process Output](https://symfony.com/doc/current/components/process.html#getting-real-time-process-output "Permalink to this headline")
When executing a long running command (like `rsync` to a remote server), you can give feedback to the end user in real-time by passing an anonymous function to the [run()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20run "Symfony\Component\Process\Process::run()") method:
```
1
2
3
4
5
6
7
8
9
10
```
```
use Symfony\Component\Process\Process;
$process = new Process(['ls', '-lsa']);
$process->run(function ($type, $buffer): void {
if (Process::ERR === $type) {
echo 'ERR > '.$buffer;
} else {
echo 'OUT > '.$buffer;
}
});
```
Note
This feature won't work as expected in servers using PHP output buffering. In those cases, either disable the [output\_buffering](https://www.php.net/manual/en/outcontrol.configuration.php) PHP option or use the [ob\_flush](https://secure.php.net/manual/en/function.ob-flush.php "ob_flush") PHP function to force sending the output buffer.
## [Running Processes Asynchronously](https://symfony.com/doc/current/components/process.html#running-processes-asynchronously "Permalink to this headline")
You can also start the subprocess and then let it run asynchronously, retrieving output and the status in your main process whenever you need it. Use the [start()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20start "Symfony\Component\Process\Process::start()") method to start an asynchronous process, the [isRunning()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20isRunning "Symfony\Component\Process\Process::isRunning()") method to check if the process is done and the [getOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getOutput "Symfony\Component\Process\Process::getOutput()") method to get the output:
```
1
2
3
4
5
6
7
8
```
```
$process = new Process(['ls', '-lsa']);
$process->start();
while ($process->isRunning()) {
// waiting for process to finish
}
echo $process->getOutput();
```
You can also wait for a process to end if you started it asynchronously and are done doing other stuff:
```
1
2
3
4
5
6
7
8
```
```
$process = new Process(['ls', '-lsa']);
$process->start();
// ... do other things
$process->wait();
// ... do things after the process has finished
```
Note
The [wait()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20wait "Symfony\Component\Process\Process::wait()") method is blocking, which means that your code will halt at this line until the external process is completed.
Note
If a `Response` is sent **before** a child process had a chance to complete, the server process will be killed (depending on your OS). It means that your task will be stopped right away. Running an asynchronous process is not the same as running a process that survives its parent process.
If you want your process to survive the request/response cycle, you can take advantage of the `kernel.terminate` event, and run your command **synchronously** inside this event. Be aware that `kernel.terminate` is called only if you use PHP-FPM.
Danger
Beware also that if you do that, the said PHP-FPM process will not be available to serve any new request until the subprocess is finished. This means you can quickly block your FPM pool if you're not careful enough. That is why it's generally way better not to do any fancy things even after the request is sent, but to use a job queue instead.
[wait()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20wait "Symfony\Component\Process\Process::wait()") takes one optional argument: a callback that is called repeatedly while the process is still running, passing in the output and its type:
```
1
2
3
4
5
6
7
8
9
10
```
```
$process = new Process(['ls', '-lsa']);
$process->start();
$process->wait(function ($type, $buffer): void {
if (Process::ERR === $type) {
echo 'ERR > '.$buffer;
} else {
echo 'OUT > '.$buffer;
}
});
```
Instead of waiting until the process has finished, you can use the [waitUntil()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20waitUntil "Symfony\Component\Process\Process::waitUntil()") method to keep or stop waiting based on some PHP logic. The following example starts a long running process and checks its output to wait until its fully initialized:
```
1
2
3
4
5
6
7
8
9
10
11
```
```
$process = new Process(['/usr/bin/php', 'slow-starting-server.php']);
$process->start();
// ... do other things
// waits until the given anonymous function returns true
$process->waitUntil(function ($type, $output): bool {
return $output === 'Ready. Waiting for commands...';
});
// ... do things after the process is ready
```
## [Streaming to the Standard Input of a Process](https://symfony.com/doc/current/components/process.html#streaming-to-the-standard-input-of-a-process "Permalink to this headline")
Before a process is started, you can specify its standard input using either the [setInput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20setInput "Symfony\Component\Process\Process::setInput()") method or the 4th argument of the constructor. The provided input can be a string, a stream resource or a `Traversable` object:
```
1
2
3
```
```
$process = new Process(['cat']);
$process->setInput('foobar');
$process->run();
```
When this input is fully written to the subprocess standard input, the corresponding pipe is closed.
In order to write to a subprocess standard input while it is running, the component provides the [InputStream](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/InputStream.php "Symfony\Component\Process\InputStream") class:
```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
```
```
$input = new InputStream();
$input->write('foo');
$process = new Process(['cat']);
$process->setInput($input);
$process->start();
// ... read process output or do other things
$input->write('bar');
$input->close();
$process->wait();
// will echo: foobar
echo $process->getOutput();
```
The [write()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/InputStream.php#:~:text=function%20write "Symfony\Component\Process\InputStream::write()") method accepts scalars, stream resources or `Traversable` objects as arguments. As shown in the above example, you need to explicitly call the [close()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/InputStream.php#:~:text=function%20close "Symfony\Component\Process\InputStream::close()") method when you are done writing to the standard input of the subprocess.
### [Using PHP Streams as the Standard Input of a Process](https://symfony.com/doc/current/components/process.html#using-php-streams-as-the-standard-input-of-a-process "Permalink to this headline")
The input of a process can also be defined using [PHP streams](https://www.php.net/manual/en/book.stream.php):
```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
```
```
$stream = fopen('php://temporary', 'w+');
$process = new Process(['cat']);
$process->setInput($stream);
$process->start();
fwrite($stream, 'foo');
// ... read process output or do other things
fwrite($stream, 'bar');
fclose($stream);
$process->wait();
// will echo: 'foobar'
echo $process->getOutput();
```
## [Using TTY and PTY Modes](https://symfony.com/doc/current/components/process.html#using-tty-and-pty-modes "Permalink to this headline")
All examples above show that your program has control over the input of a process (using `setInput()`) and the output from that process (using `getOutput()`). The Process component has two special modes that tweak the relationship between your program and the process: teletype (tty) and pseudo-teletype (pty).
In TTY mode, you connect the input and output of the process to the input and output of your program. This allows for instance to open an editor like Vim or Nano as a process. You enable TTY mode by calling [setTty()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20setTty "Symfony\Component\Process\Process::setTty()"):
```
1
2
3
4
5
6
7
```
```
$process = new Process(['vim']);
$process->setTty(true);
$process->run();
// As the output is connected to the terminal, it is no longer possible
// to read or modify the output from the process!
dump($process->getOutput()); // null
```
In PTY mode, your program behaves as a terminal for the process instead of a plain input and output. Some programs behave differently when interacting with a real terminal instead of another program. For instance, some programs prompt for a password when talking with a terminal. Use [setPty()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20setPty "Symfony\Component\Process\Process::setPty()") to enable this mode.
## [Stopping a Process](https://symfony.com/doc/current/components/process.html#stopping-a-process "Permalink to this headline")
Any asynchronous process can be stopped at any time with the [stop()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20stop "Symfony\Component\Process\Process::stop()") method. This method takes two arguments: a timeout and a signal. Once the timeout is reached, the signal is sent to the running process. The default signal sent to a process is `SIGKILL`. Please read the [signal documentation below](https://symfony.com/doc/current/components/process.html#reference-process-signal) to find out more about signal handling in the Process component:
```
1
2
3
4
5
6
```
```
$process = new Process(['ls', '-lsa']);
$process->start();
// ... do other things
$process->stop(3, SIGINT);
```
## [Executing PHP Code in Isolation](https://symfony.com/doc/current/components/process.html#executing-php-code-in-isolation "Permalink to this headline")
If you want to execute some PHP code in isolation, use the `PhpProcess` instead:
```
1
2
3
4
5
6
7
```
```
use Symfony\Component\Process\PhpProcess;
$process = new PhpProcess(<<<EOF
<?= 'Hello World' ?>
EOF
);
$process->run();
```
## [Executing a PHP Child Process with the Same Configuration](https://symfony.com/doc/current/components/process.html#executing-a-php-child-process-with-the-same-configuration "Permalink to this headline")
When you start a PHP process, it uses the default configuration defined in your `php.ini` file. You can bypass these options with the `-d` command line option. For example, if `memory_limit` is set to `256M`, you can disable this memory limit when running some command like this: `php -d memory_limit=-1 bin/console app:my-command`.
However, if you run the command via the Symfony `Process` class, PHP will use the settings defined in the `php.ini` file. You can solve this issue by using the [PhpSubprocess](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/PhpSubprocess.php "Symfony\Component\Process\PhpSubprocess") class to run the command:
```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
```
```
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Process\Process;
#[AsCommand(name: 'app:my-command')]
class MyCommand
{
public function __invoke(SymfonyStyle $io): int
{
// the memory_limit (and any other config option) of this command is
// the one defined in php.ini instead of the new values (optionally)
// passed via the '-d' command option
$childProcess = new Process(['bin/console', 'cache:pool:prune']);
// the memory_limit (and any other config option) of this command takes
// into account the values (optionally) passed via the '-d' command option
$childProcess = new PhpSubprocess(['bin/console', 'cache:pool:prune']);
return 0;
}
}
```
## [Process Timeout](https://symfony.com/doc/current/components/process.html#process-timeout "Permalink to this headline")
By default processes have a timeout of 60 seconds, but you can change it passing a different timeout (in seconds) to the `setTimeout()` method:
```
1
2
3
4
5
```
```
use Symfony\Component\Process\Process;
$process = new Process(['ls', '-lsa']);
$process->setTimeout(3600);
$process->run();
```
If the timeout is reached, a [ProcessTimedOutException](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Exception/ProcessTimedOutException.php "Symfony\Component\Process\Exception\ProcessTimedOutException") is thrown.
For long running commands, it is your responsibility to perform the timeout check regularly:
```
1
2
3
4
5
6
7
8
9
10
11
```
```
$process->setTimeout(3600);
$process->start();
while ($condition) {
// ...
// check if the timeout is reached
$process->checkTimeout();
usleep(200000);
}
```
Tip
You can get the process start time using the `getStartTime()` method.
## [Process Idle Timeout](https://symfony.com/doc/current/components/process.html#process-idle-timeout "Permalink to this headline")
In contrast to the timeout of the previous paragraph, the idle timeout only considers the time since the last output was produced by the process:
```
1
2
3
4
5
6
```
```
use Symfony\Component\Process\Process;
$process = new Process(['something-with-variable-runtime']);
$process->setTimeout(3600);
$process->setIdleTimeout(60);
$process->run();
```
In the case above, a process is considered timed out, when either the total runtime exceeds 3600 seconds, or the process does not produce any output for 60 seconds.
## [Process Signals](https://symfony.com/doc/current/components/process.html#process-signals "Permalink to this headline")
When running a program asynchronously, you can send it POSIX signals with the [signal()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20signal "Symfony\Component\Process\Process::signal()") method:
```
1
2
3
4
5
6
7
```
```
use Symfony\Component\Process\Process;
$process = new Process(['find', '/', '-name', 'rabbit']);
$process->start();
// will send a SIGKILL to the process
$process->signal(SIGKILL);
```
You can make the process ignore signals by using the [setIgnoredSignals()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20setIgnoredSignals "Symfony\Component\Process\Process::setIgnoredSignals()") method. The given signals won't be propagated to the child process:
```
1
2
3
4
```
```
use Symfony\Component\Process\Process;
$process = new Process(['find', '/', '-name', 'rabbit']);
$process->setIgnoredSignals([SIGKILL, SIGUSR1]);
```
## [Process Pid](https://symfony.com/doc/current/components/process.html#process-pid "Permalink to this headline")
You can access the [pid](https://en.wikipedia.org/wiki/Process_identifier) of a running process with the [getPid()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getPid "Symfony\Component\Process\Process::getPid()") method:
```
1
2
3
4
5
6
```
```
use Symfony\Component\Process\Process;
$process = new Process(['/usr/bin/php', 'worker.php']);
$process->start();
$pid = $process->getPid();
```
## [Disabling Output](https://symfony.com/doc/current/components/process.html#disabling-output "Permalink to this headline")
As standard output and error output are always fetched from the underlying process, it might be convenient to disable output in some cases to save memory. Use [disableOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20disableOutput "Symfony\Component\Process\Process::disableOutput()") and [enableOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20enableOutput "Symfony\Component\Process\Process::enableOutput()") to toggle this feature:
```
1
2
3
4
5
```
```
use Symfony\Component\Process\Process;
$process = new Process(['/usr/bin/php', 'worker.php']);
$process->disableOutput();
$process->run();
```
Warning
You cannot enable or disable the output while the process is running.
If you disable the output, you cannot access `getOutput()`, `getIncrementalOutput()`, `getErrorOutput()`, `getIncrementalErrorOutput()` or `setIdleTimeout()`.
However, it is possible to pass a callback to the `start`, `run` or `mustRun` methods to handle process output in a streaming fashion.
## [Finding an Executable](https://symfony.com/doc/current/components/process.html#finding-an-executable "Permalink to this headline")
The Process component provides a utility class called [ExecutableFinder](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/ExecutableFinder.php "Symfony\Component\Process\ExecutableFinder") which finds and returns the absolute path of an executable:
```
1
2
3
4
5
```
```
use Symfony\Component\Process\ExecutableFinder;
$executableFinder = new ExecutableFinder();
$chromedriverPath = $executableFinder->find('chromedriver');
// $chromedriverPath = '/usr/local/bin/chromedriver' (the result will be different on your computer)
```
The [find()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/ExecutableFinder.php#:~:text=function%20find "Symfony\Component\Process\ExecutableFinder::find()") method also takes extra parameters to specify a default value to return and extra directories where to look for the executable:
```
1
2
3
4
```
```
use Symfony\Component\Process\ExecutableFinder;
$executableFinder = new ExecutableFinder();
$chromedriverPath = $executableFinder->find('chromedriver', '/path/to/chromedriver', ['local-bin/']);
```
## [Finding the Executable PHP Binary](https://symfony.com/doc/current/components/process.html#finding-the-executable-php-binary "Permalink to this headline")
This component also provides a special utility class called [PhpExecutableFinder](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/PhpExecutableFinder.php "Symfony\Component\Process\PhpExecutableFinder") which returns the absolute path of the executable PHP binary available on your server:
```
1
2
3
4
5
```
```
use Symfony\Component\Process\PhpExecutableFinder;
$phpBinaryFinder = new PhpExecutableFinder();
$phpBinaryPath = $phpBinaryFinder->find();
// $phpBinaryPath = '/usr/local/bin/php' (the result will be different on your computer)
```
## [Checking for TTY Support](https://symfony.com/doc/current/components/process.html#checking-for-tty-support "Permalink to this headline")
Another utility provided by this component is a method called [isTtySupported()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20isTtySupported "Symfony\Component\Process\Process::isTtySupported()") which returns whether [TTY](https://en.wikipedia.org/wiki/Tty_\(unix\)) is supported on the current operating system:
```
1
2
3
```
```
use Symfony\Component\Process\Process;
$process = new Process()->setTty(Process::isTtySupported());
```
This work, including the code samples, is licensed under a [Creative Commons BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) license.
TOC
Search
Version
**Symfony 8.0** [backers](https://symfony.com/backers)
[](https://www.blackfire.io/profiler?utm_source=symfony&utm_medium=ad_black_logo&utm_campaign=profiler)
[Check Code Performance in Dev, Test, Staging & Production](https://www.blackfire.io/profiler?utm_source=symfony&utm_medium=ad_black_logo&utm_campaign=profiler)
[](https://sensiolabs.com/training/courses?utm_source=symfony&utm_medium=symfony_ads&utm_campaign=permanent_referral)
[Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).](https://sensiolabs.com/training/courses?utm_source=symfony&utm_medium=symfony_ads&utm_campaign=permanent_referral)
## Symfony footer

Thanks **Joan Cruz** for being a Symfony contributor
**1** commit • **71** lines changed
[View all contributors](https://symfony.com/contributors) that help us make Symfony
### Become a Symfony contributor
Be an active part of the community and contribute ideas, code and bug fixes. Both experts and newcomers are welcome.
[Learn how to contribute](https://symfony.com/doc/current/contributing/index.html)

[Celebrating 20 years of Symfony](https://symfony.com/20years)
**Symfony**™ is a trademark of Symfony SAS. [All rights reserved](https://symfony.com/trademark).
- [What is Symfony?](https://symfony.com/what-is-symfony)
- [What is Symfony?](https://symfony.com/what-is-symfony)
- [Symfony at a Glance](https://symfony.com/at-a-glance)
- [Symfony Packages](https://symfony.com/packages)
- [Symfony Releases](https://symfony.com/releases)
- [Security Policy](https://symfony.com/doc/current/contributing/code/security.html)
- [Logo & Screenshots](https://symfony.com/logo)
- [Trademark & Licenses](https://symfony.com/license)
- [symfony1 Legacy](https://symfony.com/legacy)
- [Learn Symfony](https://symfony.com/doc)
- [Symfony Docs](https://symfony.com/doc)
- [Symfony Book](https://symfony.com/book)
- [Reference](https://symfony.com/doc/current/reference/index.html)
- [Bundles](https://symfony.com/bundles)
- [Best Practices](https://symfony.com/doc/current/best_practices.html)
- [Training](https://sensiolabs.com/training/courses?utm_source=symfony&utm_medium=symfony_footer&utm_campaign=permanent_referral)
- [eLearning Platform](https://university.sensiolabs.com/e-learning-platform?utm_source=symfony&utm_medium=symfony_footer&utm_campaign=permanent_referral)
- [Certification](https://certification.symfony.com/)
- [Screencasts](https://symfonycasts.com/)
- [Learn Symfony](https://symfonycasts.com/tracks/symfony)
- [Learn PHP](https://symfonycasts.com/tracks/php)
- [Learn JavaScript](https://symfonycasts.com/tracks/javascript)
- [Learn Drupal](https://symfonycasts.com/tracks/drupal)
- [Learn RESTful APIs](https://symfonycasts.com/tracks/rest)
- [Community](https://symfony.com/community)
- [Symfony Community](https://symfony.com/community)
- [SymfonyConnect](https://connect.symfony.com/)
- [Events & Meetups](https://symfony.com/events/)
- [Projects using Symfony](https://symfony.com/projects)
- [Contributors](https://symfony.com/contributors)
- [Symfony Jobs](https://symfony.com/jobs)
- [Backers](https://symfony.com/backers)
- [Code of Conduct](https://symfony.com/doc/current/contributing/code_of_conduct/code_of_conduct.html)
- [Downloads Stats](https://symfony.com/stats/downloads)
- [Support](https://symfony.com/support)
- [Blog](https://symfony.com/blog/)
- [All Blog Posts](https://symfony.com/blog/)
- [A Week of Symfony](https://symfony.com/blog/category/a-week-of-symfony)
- [Case Studies](https://symfony.com/blog/category/case-studies)
- [Cloud](https://symfony.com/blog/category/cloud)
- [Community](https://symfony.com/blog/category/community)
- [Conferences](https://symfony.com/blog/category/conferences)
- [Diversity](https://symfony.com/blog/category/diversity)
- [Living on the edge](https://symfony.com/blog/category/living-on-the-edge)
- [Releases](https://symfony.com/blog/category/releases)
- [Security Advisories](https://symfony.com/blog/category/security-advisories)
- [Symfony Insight](https://symfony.com/blog/category/symfony-insight)
- [Twig](https://symfony.com/blog/category/twig)
- [SensioLabs Blog](https://sensiolabs.com/blog?utm_source=symfony&utm_medium=symfony_footer&utm_campaign=permanent_referral)
- [Services](https://sensiolabs.com/?utm_source=symfony&utm_medium=symfony_footer&utm_campaign=permanent_referral)
- [SensioLabs services](https://sensiolabs.com/?utm_source=symfony&utm_medium=symfony_footer&utm_campaign=permanent_referral)
- [Train developers](https://sensiolabs.com/training?utm_source=symfony&utm_medium=symfony_footer&utm_campaign=permanent_referral)
- [Manage your project quality](https://insight.symfony.com/)
- [Improve your project performance](https://www.blackfire.io/?utm_source=symfony&utm_medium=symfonycom_footer&utm_campaign=profiler)
- [Host Symfony projects](https://symfony.com/cloud/)
[Powered by](https://symfony.com/cloud/)
[Formerly Platform.sh](https://symfony.com/cloud/ "Upsun, a Platform-as-a-Service optimized for Symfony developers")
### Follow Symfony
CLOSE |
| Readable Markdown | > The Process component executes commands in sub-processes.
## [Installation](https://symfony.com/doc/current/components/process.html#installation "Permalink to this headline")
Note
If you install this component outside of a Symfony application, you must require the `vendor/autoload.php` file in your code to enable the class autoloading mechanism provided by Composer. Read [this article](https://symfony.com/doc/current/components/using_components.html) for more details.
## [Usage](https://symfony.com/doc/current/components/process.html#usage "Permalink to this headline")
The [Process](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php "Symfony\Component\Process\Process") class executes a command in a sub-process, taking care of the differences between operating system and escaping arguments to prevent security issues. It replaces PHP functions like [exec](https://secure.php.net/manual/en/function.exec.php "exec"), [passthru](https://secure.php.net/manual/en/function.passthru.php "passthru"), [shell\_exec](https://secure.php.net/manual/en/function.shell-exec.php "shell_exec") and [system](https://secure.php.net/manual/en/function.system.php "system"):
The `getOutput()` method always returns the whole content of the standard output of the command and `getErrorOutput()` the content of the error output. Alternatively, the [getIncrementalOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getIncrementalOutput "Symfony\Component\Process\Process::getIncrementalOutput()") and [getIncrementalErrorOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getIncrementalErrorOutput "Symfony\Component\Process\Process::getIncrementalErrorOutput()") methods return the new output since the last call.
The [clearOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20clearOutput "Symfony\Component\Process\Process::clearOutput()") method clears the contents of the output and [clearErrorOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20clearErrorOutput "Symfony\Component\Process\Process::clearErrorOutput()") clears the contents of the error output.
You can also use the [Process](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php "Symfony\Component\Process\Process") class with the for each construct to get the output while it is generated. By default, the loop waits for new output before going to the next iteration:
Tip
The Process component internally uses a PHP iterator to get the output while it is generated. That iterator is exposed via the `getIterator()` method to allow customizing its behavior:
The `mustRun()` method is identical to `run()`, except that it will throw a [ProcessFailedException](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Exception/ProcessFailedException.php "Symfony\Component\Process\Exception\ProcessFailedException") if the process couldn't be executed successfully (i.e. the process exited with a non-zero code):
Tip
You can get the last output time in seconds by using the [getLastOutputTime()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getLastOutputTime "Symfony\Component\Process\Process::getLastOutputTime()") method. This method returns `null` if the process wasn't started\!
## [Configuring Process Options](https://symfony.com/doc/current/components/process.html#configuring-process-options "Permalink to this headline")
Symfony uses the PHP [proc\_open](https://secure.php.net/manual/en/function.proc-open.php "proc_open") function to run the processes. You can configure the options passed to the `other_options` argument of `proc_open()` using the `setOptions()` method:
Warning
Most of the options defined by `proc_open()` (such as `create_new_console` and `suppress_errors`) are only supported on Windows operating systems. Check out the [PHP documentation for proc\_open()](https://www.php.net/manual/en/function.proc-open.php) before using them.
## [Using Features From the OS Shell](https://symfony.com/doc/current/components/process.html#using-features-from-the-os-shell "Permalink to this headline")
Using an 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 while they run):
If you need to use stream redirections, conditional execution, or any other feature provided by the shell of your operating system, you can also define commands as strings using the [fromShellCommandline()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20fromShellCommandline "Symfony\Component\Process\Process::fromShellCommandline()") static factory.
Each operating system provides a different syntax for their command-lines, so it becomes your responsibility to deal with escaping and portability.
When using strings to define commands, variable arguments are passed as environment variables using the second argument of the `run()`, `mustRun()` or `start()` methods. Referencing them is also OS-dependent:
If you prefer to create portable commands that are independent from the operating system, you can write the above command as follows:
Portable commands require using a syntax that is specific to the component: when enclosing a variable name into `"${:` and `}"` exactly, the process object will replace it with its escaped value, or will fail if the variable is not found in the list of environment variables attached to the command.
## [Setting Environment Variables for Processes](https://symfony.com/doc/current/components/process.html#setting-environment-variables-for-processes "Permalink to this headline")
The constructor of the [Process](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php "Symfony\Component\Process\Process") class and all of its methods related to executing processes (`run()`, `mustRun()`, `start()`, etc.) allow passing an array of environment variables to set while running the process:
In addition to the env vars passed explicitly, processes inherit all the env vars defined in your system. You can prevent this by setting the env vars you want to remove to `false`:
## [Getting real-time Process Output](https://symfony.com/doc/current/components/process.html#getting-real-time-process-output "Permalink to this headline")
When executing a long running command (like `rsync` to a remote server), you can give feedback to the end user in real-time by passing an anonymous function to the [run()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20run "Symfony\Component\Process\Process::run()") method:
Note
This feature won't work as expected in servers using PHP output buffering. In those cases, either disable the [output\_buffering](https://www.php.net/manual/en/outcontrol.configuration.php) PHP option or use the [ob\_flush](https://secure.php.net/manual/en/function.ob-flush.php "ob_flush") PHP function to force sending the output buffer.
## [Running Processes Asynchronously](https://symfony.com/doc/current/components/process.html#running-processes-asynchronously "Permalink to this headline")
You can also start the subprocess and then let it run asynchronously, retrieving output and the status in your main process whenever you need it. Use the [start()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20start "Symfony\Component\Process\Process::start()") method to start an asynchronous process, the [isRunning()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20isRunning "Symfony\Component\Process\Process::isRunning()") method to check if the process is done and the [getOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getOutput "Symfony\Component\Process\Process::getOutput()") method to get the output:
You can also wait for a process to end if you started it asynchronously and are done doing other stuff:
Note
The [wait()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20wait "Symfony\Component\Process\Process::wait()") method is blocking, which means that your code will halt at this line until the external process is completed.
Note
If a `Response` is sent **before** a child process had a chance to complete, the server process will be killed (depending on your OS). It means that your task will be stopped right away. Running an asynchronous process is not the same as running a process that survives its parent process.
If you want your process to survive the request/response cycle, you can take advantage of the `kernel.terminate` event, and run your command **synchronously** inside this event. Be aware that `kernel.terminate` is called only if you use PHP-FPM.
Danger
Beware also that if you do that, the said PHP-FPM process will not be available to serve any new request until the subprocess is finished. This means you can quickly block your FPM pool if you're not careful enough. That is why it's generally way better not to do any fancy things even after the request is sent, but to use a job queue instead.
[wait()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20wait "Symfony\Component\Process\Process::wait()") takes one optional argument: a callback that is called repeatedly while the process is still running, passing in the output and its type:
Instead of waiting until the process has finished, you can use the [waitUntil()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20waitUntil "Symfony\Component\Process\Process::waitUntil()") method to keep or stop waiting based on some PHP logic. The following example starts a long running process and checks its output to wait until its fully initialized:
## [Streaming to the Standard Input of a Process](https://symfony.com/doc/current/components/process.html#streaming-to-the-standard-input-of-a-process "Permalink to this headline")
Before a process is started, you can specify its standard input using either the [setInput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20setInput "Symfony\Component\Process\Process::setInput()") method or the 4th argument of the constructor. The provided input can be a string, a stream resource or a `Traversable` object:
When this input is fully written to the subprocess standard input, the corresponding pipe is closed.
In order to write to a subprocess standard input while it is running, the component provides the [InputStream](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/InputStream.php "Symfony\Component\Process\InputStream") class:
The [write()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/InputStream.php#:~:text=function%20write "Symfony\Component\Process\InputStream::write()") method accepts scalars, stream resources or `Traversable` objects as arguments. As shown in the above example, you need to explicitly call the [close()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/InputStream.php#:~:text=function%20close "Symfony\Component\Process\InputStream::close()") method when you are done writing to the standard input of the subprocess.
## [Using TTY and PTY Modes](https://symfony.com/doc/current/components/process.html#using-tty-and-pty-modes "Permalink to this headline")
All examples above show that your program has control over the input of a process (using `setInput()`) and the output from that process (using `getOutput()`). The Process component has two special modes that tweak the relationship between your program and the process: teletype (tty) and pseudo-teletype (pty).
In TTY mode, you connect the input and output of the process to the input and output of your program. This allows for instance to open an editor like Vim or Nano as a process. You enable TTY mode by calling [setTty()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20setTty "Symfony\Component\Process\Process::setTty()"):
In PTY mode, your program behaves as a terminal for the process instead of a plain input and output. Some programs behave differently when interacting with a real terminal instead of another program. For instance, some programs prompt for a password when talking with a terminal. Use [setPty()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20setPty "Symfony\Component\Process\Process::setPty()") to enable this mode.
## [Stopping a Process](https://symfony.com/doc/current/components/process.html#stopping-a-process "Permalink to this headline")
Any asynchronous process can be stopped at any time with the [stop()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20stop "Symfony\Component\Process\Process::stop()") method. This method takes two arguments: a timeout and a signal. Once the timeout is reached, the signal is sent to the running process. The default signal sent to a process is `SIGKILL`. Please read the [signal documentation below](https://symfony.com/doc/current/components/process.html#reference-process-signal) to find out more about signal handling in the Process component:
## [Executing PHP Code in Isolation](https://symfony.com/doc/current/components/process.html#executing-php-code-in-isolation "Permalink to this headline")
If you want to execute some PHP code in isolation, use the `PhpProcess` instead:
## [Executing a PHP Child Process with the Same Configuration](https://symfony.com/doc/current/components/process.html#executing-a-php-child-process-with-the-same-configuration "Permalink to this headline")
When you start a PHP process, it uses the default configuration defined in your `php.ini` file. You can bypass these options with the `-d` command line option. For example, if `memory_limit` is set to `256M`, you can disable this memory limit when running some command like this: `php -d memory_limit=-1 bin/console app:my-command`.
However, if you run the command via the Symfony `Process` class, PHP will use the settings defined in the `php.ini` file. You can solve this issue by using the [PhpSubprocess](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/PhpSubprocess.php "Symfony\Component\Process\PhpSubprocess") class to run the command:
## [Process Timeout](https://symfony.com/doc/current/components/process.html#process-timeout "Permalink to this headline")
By default processes have a timeout of 60 seconds, but you can change it passing a different timeout (in seconds) to the `setTimeout()` method:
If the timeout is reached, a [ProcessTimedOutException](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Exception/ProcessTimedOutException.php "Symfony\Component\Process\Exception\ProcessTimedOutException") is thrown.
For long running commands, it is your responsibility to perform the timeout check regularly:
Tip
You can get the process start time using the `getStartTime()` method.
## [Process Idle Timeout](https://symfony.com/doc/current/components/process.html#process-idle-timeout "Permalink to this headline")
In contrast to the timeout of the previous paragraph, the idle timeout only considers the time since the last output was produced by the process:
In the case above, a process is considered timed out, when either the total runtime exceeds 3600 seconds, or the process does not produce any output for 60 seconds.
## [Process Signals](https://symfony.com/doc/current/components/process.html#process-signals "Permalink to this headline")
When running a program asynchronously, you can send it POSIX signals with the [signal()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20signal "Symfony\Component\Process\Process::signal()") method:
You can make the process ignore signals by using the [setIgnoredSignals()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20setIgnoredSignals "Symfony\Component\Process\Process::setIgnoredSignals()") method. The given signals won't be propagated to the child process:
## [Process Pid](https://symfony.com/doc/current/components/process.html#process-pid "Permalink to this headline")
You can access the [pid](https://en.wikipedia.org/wiki/Process_identifier) of a running process with the [getPid()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20getPid "Symfony\Component\Process\Process::getPid()") method:
## [Disabling Output](https://symfony.com/doc/current/components/process.html#disabling-output "Permalink to this headline")
As standard output and error output are always fetched from the underlying process, it might be convenient to disable output in some cases to save memory. Use [disableOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20disableOutput "Symfony\Component\Process\Process::disableOutput()") and [enableOutput()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20enableOutput "Symfony\Component\Process\Process::enableOutput()") to toggle this feature:
Warning
You cannot enable or disable the output while the process is running.
If you disable the output, you cannot access `getOutput()`, `getIncrementalOutput()`, `getErrorOutput()`, `getIncrementalErrorOutput()` or `setIdleTimeout()`.
However, it is possible to pass a callback to the `start`, `run` or `mustRun` methods to handle process output in a streaming fashion.
## [Finding an Executable](https://symfony.com/doc/current/components/process.html#finding-an-executable "Permalink to this headline")
The Process component provides a utility class called [ExecutableFinder](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/ExecutableFinder.php "Symfony\Component\Process\ExecutableFinder") which finds and returns the absolute path of an executable:
The [find()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/ExecutableFinder.php#:~:text=function%20find "Symfony\Component\Process\ExecutableFinder::find()") method also takes extra parameters to specify a default value to return and extra directories where to look for the executable:
## [Finding the Executable PHP Binary](https://symfony.com/doc/current/components/process.html#finding-the-executable-php-binary "Permalink to this headline")
This component also provides a special utility class called [PhpExecutableFinder](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/PhpExecutableFinder.php "Symfony\Component\Process\PhpExecutableFinder") which returns the absolute path of the executable PHP binary available on your server:
## [Checking for TTY Support](https://symfony.com/doc/current/components/process.html#checking-for-tty-support "Permalink to this headline")
Another utility provided by this component is a method called [isTtySupported()](https://github.com/symfony/symfony/blob/8.0/src/Symfony/Component/Process/Process.php#:~:text=function%20isTtySupported "Symfony\Component\Process\Process::isTtySupported()") which returns whether [TTY](https://en.wikipedia.org/wiki/Tty_\(unix\)) is supported on the current operating system:
This work, including the code samples, is licensed under a [Creative Commons BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) license. |
| Shard | 148 (laksa) |
| Root Hash | 16968411856917244348 |
| Unparsed URL | com,symfony!/doc/current/components/process.html s443 |