How to display Laravel artisan command output on same line?
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
How to Display Laravel Artisan Command Output on the Same Line: Mastering Real-Time Progress
As developers, we often deal with executing long-running tasks, whether it’s processing data, running migrations, or deploying code via Artisan commands. A critical part of a good user experience is providing feedback during these operations. The desire to show a simple progress indicator—like dots (. . .)—on the same line as the command output is completely valid.
The challenge arises because when you execute an external process, such as an Artisan command via PHP's shell execution functions, you are dealing with two distinct streams of data: your application’s custom status updates and the command’s standard output. As you noted, simply echoing characters within a script often forces new lines, breaking the desired visual flow when interacting with the command line environment.
This post will dive into why this happens and how senior developers solve this problem by managing the output stream directly, ensuring your progress indicators remain perfectly aligned with the execution log.
Understanding the Output Stream Limitation
When you run a command like php artisan make:model Post, the process executes in a separate environment. Any output it generates is piped to the standard output (STDOUT). If your PHP script attempts to print status updates sequentially, each echo call is treated as a separate instruction by the shell, resulting in line breaks between each piece of information.
To achieve a seamless, same-line display, you cannot rely solely on standard stream output; you must control exactly what gets sent to the terminal and ensure your progress tracker is rendered alongside it. This requires a custom approach where you manage the entire display buffer yourself, rather than letting the system handle simple echo commands.
The Developer Solution: Custom Stream Management
The most robust way to solve this is to stop trying to inject characters into the execution stream and instead manage the presentation layer entirely within your application logic. This means treating the command execution as an iterative process where you manually control the cursor position or use carriage returns (\r) to overwrite the previous line.
Here is a conceptual example demonstrating how you might structure this logic when wrapping an external process:
<?php
function run_with_progress(string $command, int $totalSteps)
{
echo "Starting process...\n";
$progress = 0;
// Execute the command iteratively (conceptual example for demonstration)
for ($i = 1; $i <= $totalSteps; $i++) {
// Output the progress indicator using carriage return (\r)
// \r moves the cursor to the start of the line without advancing to the next line.
echo "\rProcessing step $i of $totalSteps... " . str_repeat('.', $i) . "\r";
// Simulate work being done (in a real scenario, you would poll the command result)
sleep(1);
$progress = $i;
// Flush the output buffer to ensure immediate display
flush();
}
// Print a final newline to move the cursor past the progress bar
echo "\nProcess complete!\n";
}
// Example usage:
run_with_progress('php artisan migrate --force', 10);
Key Takeaways from the Example
Notice the use of \r (carriage return). This special character tells the terminal to move the cursor back to the beginning of the current line. By combining this with outputting the progress string and then immediately flushing the buffer, we effectively overwrite the previous line, creating the illusion that the status update is happening "on the same line."
This technique is foundational for building sophisticated command-line interfaces (CLIs) within Laravel applications or any shell wrapper. For more complex orchestration of tasks, understanding how Laravel manages background jobs and process management—concepts heavily emphasized in robust systems like those found at laravelcompany.com—is invaluable for managing asynchronous feedback effectively.
Conclusion
Displaying real-time progress on the same line requires shifting perspective from simple output echoing to active stream control. By mastering characters like \r and explicitly flushing the output buffer, you gain granular control over what the user sees in their terminal. While executing complex Artisan commands might seem isolated, wrapping them with custom logic allows you to build superior, interactive tooling around those core Laravel functionalities. Embrace stream management, and you can deliver a much smoother experience for your users.