How do i get the terminal text from a GNU Screen session in PHP? I am puzzled because GitHub CoPilot suggest i can do
function getTerminalTextFromGnuScreen(string $screenName): string
{
$screenText = shell_exec("screen -S " . escapeshellarg($screenName) . " -X hardcopy -h");
return $screenText;
}
but that does not actually get me anything, just emptystring. I came up with a much more complex, convoluted, and dodgy implementation, which works, but i hope, as CoPilot suggest, that there is a much easier way to do this, hence asking here: how should it be done? my dodgy implementation:
function getTerminalTextFromGnuScreenDodgy(string $screenName, bool $skipTerminalSizeControlCharacters = true): string
{
// the double escapeshellarg is intentional.
$cmd = 'script --command ' . escapeshellarg('screen -x -r ' . escapeshellarg($screenName)) . ' /dev/null ';
$proc = proc_open($cmd, [['pipe', 'rb'], ['pipe', 'wb'], ['pipe', 'wb']], $pipes);
stream_set_blocking($pipes[1], true);
fgets($pipes[1]); // skip "Script started, output log file is '/dev/null'." line
$ret = '';
if ($skipTerminalSizeControlCharacters) {
$ret = fgets($pipes[1]); // contains terminal size characters
$lastControlCharacter = strrpos($ret, "\x1b"); // THIS IS NOT 100% RELIABLE, and i don't know how to make it reliable either :(
$ret = substr($ret, $lastControlCharacter + strlen("\x1b[2J")); // skip terminal size characters
}
stream_set_blocking($pipes[1], false);
for (;;) {
$r = [$pipes[1]];
$w = $e = null;
$sel = stream_select($r, $w, $e, 0, 10000);
$tmp = stream_get_contents($pipes[1]);
if ($tmp === false || $tmp === '') {
break;
}
$ret .= $tmp;
}
fclose($pipes[1]);
// send ctrl+AD... why is \x01 equivalent to ctrl+AD? i have no idea! but it seems to work
fwrite($pipes[0], "\x01");
fclose($pipes[0]);
fclose($pipes[2]); // contains a "script: write error" message.. no idea why.
proc_close($proc);
return $ret;
}
so much wasted effort.. the answer is indeed
-X hardcopy, but the the code refuse to writes to bothstdoutand/dev/stdout, and if you tell it to write to the filename-which traditionally meansstdout, it will write to./-, and if no file is given it default to the filename "hardcopy.n" -Why? I have no idea, but regardless, use
tmpfile()to get a output file for -X hardcopy:-hargument, but the documentation over at https://www.gnu.org/software/screen/manual/screen.html says