I am building a cli tool in node.js (for mac, bash), which lets you interactively construct a command and run it. for example, you can run "node myTool", and then it asks you some questions and at the end runs a command. The thing is, I want the user to be able to run the final command again by pressing the "up" key. currently, when the user presses "up" he gets: "node myTool", but I want instead to give him the actual command that was running. I was able to do it in bash, by manipulating the history like this:
echo 'final command' >> $HISTFILE && history -r $HISTFILE
this actually works, and when I press "up" I see "final command", but It doesn't work from node.js by using execSync:
execSync(`echo 'final command' >> $HISTFILE && history -r $HISTFILE`);
It successfully appends "final command" to the history, but for obvious reasons, "history -r" doesn't refresh the terminal. is there a way to actually refresh the terminal's history for the user to achieve the expected result??
You're running
history -rin a new shell process, not the user's original interactive shell. Each shell process keeps its own history, and reloading the child shell's history has no effect on the parent shell's history.In general, there's no direct way to modify the state of the parent shell. Programs that are intended to do this work by outputting shell commands. The user makes use of them by getting the output with a command substitution, then using
evalto execute it (an example of this istset).So you could change your node.js script to
Then you could use it as
But in this case the script can't do any "normal" output to stdout, since anything it prints will be executed by
evalrather than displayed on the terminal.