From 210d3b37366625115278b227d72c3d93184e511b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 15 Mar 2026 13:23:35 +0000 Subject: [PATCH 1/3] Initial plan From 777b7c4fc7dee733f572ad8bb9a07ee996ef70c0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 15 Mar 2026 13:33:02 +0000 Subject: [PATCH 2/3] Add ksh support: detect ksh shells and use POSIX-compatible read commands Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- src/WP_CLI/Shell/REPL.php | 58 ++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/src/WP_CLI/Shell/REPL.php b/src/WP_CLI/Shell/REPL.php index 63e1b348..530705e3 100644 --- a/src/WP_CLI/Shell/REPL.php +++ b/src/WP_CLI/Shell/REPL.php @@ -125,8 +125,8 @@ private static function create_prompt_cmd( $prompt, $history_path ) { } elseif ( is_file( '/bin/bash' ) && is_readable( '/bin/bash' ) ) { // Prefer /bin/bash when available since we use bash-specific commands. $shell_binary = '/bin/bash'; - } elseif ( getenv( 'SHELL' ) && self::is_bash_shell( (string) getenv( 'SHELL' ) ) ) { - // Only use SHELL as fallback if it's bash (we use bash-specific commands). + } elseif ( getenv( 'SHELL' ) && self::is_supported_shell( (string) getenv( 'SHELL' ) ) ) { + // Use SHELL as fallback if it's a supported shell (bash or ksh). $shell_binary = (string) getenv( 'SHELL' ); } else { // Final fallback for systems without /bin/bash. @@ -137,16 +137,27 @@ private static function create_prompt_cmd( $prompt, $history_path ) { WP_CLI::error( "The shell binary '{$shell_binary}' is not valid. You can override the shell to be used through the WP_CLI_CUSTOM_SHELL environment variable." ); } + $is_ksh = self::is_ksh_shell( $shell_binary ); $shell_binary = escapeshellarg( $shell_binary ); - $cmd = 'set -f; ' - . "history -r {$history_path}; " - . 'LINE=""; ' - . "read -re -p {$prompt} LINE; " - . '[ $? -eq 0 ] || exit; ' - . 'history -s -- "$LINE"; ' - . "history -w {$history_path}; " - . 'echo $LINE; '; + if ( $is_ksh ) { + // ksh does not support bash-specific history commands or `read -e`/`read -p`. + // Use POSIX-compatible read and print the prompt via printf to stderr. + $cmd = 'set -f; ' + . 'LINE=""; ' + . "printf %s {$prompt} >&2; " + . 'IFS= read -r LINE || exit; ' + . 'printf \'%s\n\' "$LINE"; '; + } else { + $cmd = 'set -f; ' + . "history -r {$history_path}; " + . 'LINE=""; ' + . "read -re -p {$prompt} LINE; " + . '[ $? -eq 0 ] || exit; ' + . 'history -s -- "$LINE"; ' + . "history -w {$history_path}; " + . 'echo $LINE; '; + } return "{$shell_binary} -c " . escapeshellarg( $cmd ); } @@ -166,6 +177,33 @@ private static function is_bash_shell( $shell_path ) { return 'bash' === $basename || 0 === strpos( $basename, 'bash-' ); } + /** + * Check if a shell binary is ksh or a ksh-compatible shell (mksh, pdksh, ksh93, etc.). + * + * @param string $shell_path Path to the shell binary. + * @return bool True if the shell is ksh-compatible, false otherwise. + */ + private static function is_ksh_shell( $shell_path ) { + if ( ! is_file( $shell_path ) || ! is_readable( $shell_path ) ) { + return false; + } + $basename = basename( $shell_path ); + // Matches ksh, ksh93, ksh88, mksh, pdksh, etc. + return 0 === strpos( $basename, 'ksh' ) + || 'mksh' === $basename + || 'pdksh' === $basename; + } + + /** + * Check if a shell binary is supported (bash or ksh-compatible). + * + * @param string $shell_path Path to the shell binary. + * @return bool True if the shell is supported, false otherwise. + */ + private static function is_supported_shell( $shell_path ) { + return self::is_bash_shell( $shell_path ) || self::is_ksh_shell( $shell_path ); + } + private function set_history_file() { $data = getcwd() . get_current_user(); From 4cbcd04d9d6c2ad5ee0959ca8b0853d3dbce8f0e Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Sun, 15 Mar 2026 20:15:35 +0100 Subject: [PATCH 3/3] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/WP_CLI/Shell/REPL.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WP_CLI/Shell/REPL.php b/src/WP_CLI/Shell/REPL.php index 530705e3..a1efbafc 100644 --- a/src/WP_CLI/Shell/REPL.php +++ b/src/WP_CLI/Shell/REPL.php @@ -156,7 +156,7 @@ private static function create_prompt_cmd( $prompt, $history_path ) { . '[ $? -eq 0 ] || exit; ' . 'history -s -- "$LINE"; ' . "history -w {$history_path}; " - . 'echo $LINE; '; + . 'printf \'%s\n\' "$LINE"; '; } return "{$shell_binary} -c " . escapeshellarg( $cmd );