PHP exec() hangs during SSH command execution on RHEL 9 and returns no output or status

5 days ago 10
ARTICLE AD BOX

I am executing an SSH command on a remote host using PHP’s exec() function inside a foreach loop. Based on a condition, the command runs only during the 4th and 6th iterations. The same SSH command is executed in both iterations.

In the 4th iteration, the command executes successfully, produces output, and the script continues to the next iteration as expected. However, during the 6th iteration, the command completes successfully on the remote host, but the PHP script hangs—exec() does not return any output or exit status, and the code does not proceed to the next line. Because of this, the browser progress bar never finishes loading.

$cmd = "ssh -x user@<remotehost> sudo /acorn/bin/upgrade y"; exec($cmd, $output, $result);

In the 4th iteration, I copy an upgrade image to the /tmp directory on the remote host, then run the upgrade y command. This works correctly and returns output.

In the 6th iteration, I move a partition file to the /tmp directory and then run the same upgrade y command. The upgrade completes successfully on the remote host, but PHP hangs because exec() does not return any output or result.

I suspect that session_write_close() (called after exec()) might be affecting execution. Can session_write_close() cause exec() to block or hang?

I tried the following workarounds, but none resolved the issue:

Called session_write_close() after exec(), then restarted the session using session_start().

Replaced exec() with proc_open(), but still no output or result.

Since the SSH command runs for a long time, I added a timeout to the SSH command. This resulted in: sudo: a password is required Shared connection to <remotehost> closed.

To fix the password issue, I configured passwordless sudo for the upgrade y command and added in sudoers file:

Defaults:user !requiretty user ALL=(ALL) NOPASSWD: /acorn/bin/upgrade*

on the remote host—but the issue persists.

Tried forcing output to the browser using ob_implicit_flush(true), along with combinations of ob_start(), ob_flush(), flush(), and ob_end_flush(). This did not resolve the issue.

Executed the SSH command using sudo -n and BatchMode=yes to avoid password prompts, experimented with removing -tt to change TTY behavior, and configured passwordless sudo scoped specifically to the full command path and arguments. Despite this, exec() still hangs on RHEL 9.

Note: This same PHP code works correctly on CentOS. The issue started only after migrating to RHEL 9.

Read Entire Article