Skip to content

Conversation

@seabo
Copy link
Contributor

@seabo seabo commented Sep 10, 2023

This turned out to be harder to do than I thought and the solution here feels a tad hacky, but overall not too bad.

Because we want to run the commands in a persistent shell, and shells are for humans to write prompts in, it's actually not super easy to know when the last executed command has finished. We create a shell process by spawing sh and then all the 'real' commands are done by writing to stdin and reading from stdout/stderr (just like if you're using a terminal to work with a shell). In a tty, you get a prompt printed when the last command has finished executing, but this doesn't happen when running sh not in a tty (such as spawing a child process from node.js).

To work around it, we create a unique id for each command, and then echo that id to stdout after the main command. We can listen on stdout and receive the real command's output, and when we see that unique id (which should never accidentally appear in the real output), we know to stop reading and return everything else to the caller.

In addition to this, we use echo $? to retrieve the exit code of the main command. There's a bit of string manipulation to get all the relevant output back out of the stdout stream.

image

@seabo
Copy link
Contributor Author

seabo commented Sep 10, 2023

TODO: There should really be a method to gracefully shut down the shell process.

let shellFile = "/bin/sh";
if (process.platform === "win32") {
shellFile = process.env.comspec || "cmd.exe";
} else if (process.platform === "android") {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what

});
}

createShellProcess(shell?: string) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shell here isn't used

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh wait it's used further down. think the code could be slightly clearer (and not go through the process.platform checks if that work's going to be ignored anyway)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants