[Solved] Processes opened for update won't respond to data written to them
Posted: Sat Jan 05, 2019 2:24 am
I've been working on a field that behaves like a terminal emulator, but it's only half-working. When you press the Return key, whatever command you've typed is supposed to be written to the user's shell. So far my implementation sort-of works, but any commands I send just seem to disappear into a void. The shell doesn't respond at all, or at least that's how it seems.
I also used SSH and TELNET with what appeared to be a functioning terminal, but the same problem with processes not responding to written commands is still present. I can connect and login to my Raspberry Pi, but I can't execute commands once I'm successfully logged in. I can connect to my POP3 server, but I can't seem to send the commands to let me interact with it.
I'm scratching my head on this one, and I think it has something to do with "open process" being a Psudo-Terminal? IDK, but I would love some perspective on this. Please let me know if you have any questions, tips, criticisms. Thank you
Testing:
I also used SSH and TELNET with what appeared to be a functioning terminal, but the same problem with processes not responding to written commands is still present. I can connect and login to my Raspberry Pi, but I can't execute commands once I'm successfully logged in. I can connect to my POP3 server, but I can't seem to send the commands to let me interact with it.
I'm scratching my head on this one, and I think it has something to do with "open process" being a Psudo-Terminal? IDK, but I would love some perspective on this. Please let me know if you have any questions, tips, criticisms. Thank you
Testing:
- Create a new scrolling field called "terminal", in a new blank stack.
- Set the script of field "terminal" to...
Code: Select all
global _Terminal ### Monitor for data to write to the command on returnInField ### Collect the data to send put the lineIndex of selectedChunk into _Terminal["send_line"] put line _Terminal["send_line"] of field "terminal" into _Terminal["send_line_data"] put _Terminal["send_line_data"] &cr after _Terminal["output"] ### Internal Commands switch _Terminal["send_line_data"] case "termDisconnect" termDisconnect pass returnInField break case "clear" put empty into _Terminal["output"] put empty into fld "terminal" focus field "terminal" pass returnInField break end switch ### Custom Command if ( word 1 of _Terminal["send_line_data"] ) is "termConnect" then termOpen ( char 13 to -1 of _Terminal["send_line_data"] ) pass returnInField end if ### Send the command termCommand pass returnInField end returnInField command termCommand ### If disconnected, connect to the Shell if _Terminal["command"] is empty then termOpen ( the shellCommand ) ### Do we need to actually send anything? if _Terminal["send_line_data"] is not empty then ### Remove anything prefixed from the Terminal Output if _Terminal["prefix"] is not empty then replace _Terminal["prefix"] with "" in _Terminal["send_line_data"] ### Remember this command so we can arrow through it. put _Terminal["send_line_data"] &cr after _Terminal["send_history"] ### outputLineEndings local tOutputEnd put outputLineEndings into tOutputEnd termComment ( "Writing" && quote & _Terminal["send_line_data"] & quote ) write _Terminal["send_line_data"] to process _Terminal["command"] ### Update the Output ### There has to be a better way to do this if it is not empty then put it after _Terminal["output"] termFocus end if ### Check for errors switch the result case "eof" ### Command is closed termComment "end of file" termDisconnect exit termCommand break case "process is not open for read" ### Command is closed termComment "process is not open for read" termDisconnect exit termCommand break case not empty ### Unknown result termComment ( "result:" && the result ) break end switch end if end termCommand ### termOpen "/bin/bash" ### termOpen "/bin/sh" command termOpen tCommand ### Windows only? set hideConsoleWindows to false ### New Command Data put tCommand into _Terminal["command"] ### Open the Command termComment "Opening" open process _Terminal["command"] for text update if it is not empty then put it after _Terminal["output"] termFocus end if ### Check for errors switch the result case "eof" ### Command is closed termComment "end of file" termDisconnect exit termOpen break case "process is not open for read" ### Command is closed termComment "process is not open for read" termDisconnect exit termOpen break case not empty ### Unknown result termComment ( the result ) break end switch ### Start polling automatically termQueue end termOpen command termQueue if _Terminal["command"] is not empty then ### Remove Extra messages termPrune ### Send newest message send "termPoll" to me in 500 milliseconds put the result into _Terminal["poll_id"] else termComment "termQueue issued but nothing is open" end if end termQueue command termPrune ### Check for extra polling commands to remove local tPendingIDs put pendingMessages() into tPendingIDs filter lines of tPendingIDs with "termPoll" if ( number of lines in tPendingIDs ) > 0 then ### There they are! Get 'em! set itemDelimiter to comma repeat with x = 1 to the number of lines in tPendingIDs cancel ( item 1 of line x of tPendingIDs ) end repeat end if end termPrune command termPoll ### Get any new information from the process ### blocking: linefeed, OEF, end read from process _Terminal["command"] at 0 until empty ### Update the Output ### There has to be a better way to do this if it is not empty then put it &cr after _Terminal["output"] termFocus end if ### Check for errors switch the result case "eof" ### Command is closed termComment "end of file" termDisconnect exit termPoll break case "process is not open for read" ### Command is closed termComment "process is not open for read" termDisconnect exit termPoll break case not empty ### Unknown result termComment ( the result ) break end switch ### Start polling termQueue end termPoll ### termComment "Process is no longer open" ##! Add a Verbose flag to turn this off command termComment tComment if _Terminal["command"] is empty then put ( "[terminal]" && tComment &cr ) after _Terminal["output"] else put ( "[terminal]" && word 1 of _Terminal["command"] & ":" && tComment &cr ) after _Terminal["output"] end if put _Terminal["output"] into field "terminal" termFocus end termComment command termDisconnect tKill termPrune close process _Terminal["command"] put empty into _Terminal["command"] if tKill is true then delete global _Terminal termFocus end termDisconnect command termFocus lock screen put _Terminal["output"] into field "terminal" put charIndex of the last char of field "terminal" into _Terminal["prefix_end"] put charIndex of the last line of field "terminal" into _Terminal["prefix_start"] put _Terminal["prefix_end"] - _Terminal["prefix_start"] into _Terminal["prefix_width"] put char _Terminal["prefix_start"] to _Terminal["prefix_end"] of field "terminal" into _Terminal["prefix"] select the last char of field "terminal" unlock screen end termFocus
- Type any command to send it to your user shell. I usually just use simple stuff like "ls", "cd", or "uname -a".
- You can also connect directly to a process with termConnect. For example...
Direct connections is where I typically see the most activity from processes, but usually in terms of a connection response. For example, SSH to my Raspberry Pi resulted in a Credentials system dialog being presented, and my POP3 client connection was actively kicked by my server for inactivity and I received a full response. So again, it sort-of works.
Code: Select all
termConnect ssh -tt user@server termConnect telnet mail.server 110 termConnect uname -a
- termDisconnect is the current way to disconnect from the open process, but sometimes it doesn't work. It also doesn't support concurrent connections, so it's totally possible to have several processes open by accident. I usually have the msg box open for performing manual disconnections.
Code: Select all
termDisconnect