I will describe first environment:
Windows pc, running make in powershell. Make is using bash as its shell. I also use Windows terminal. So powershell is running in Windows terminal, calling of make target.
Problem:
When I run any target (that has at least some shell call) and press eg. arrow up, at the end of make call, I get [A printed in powershell.
My goal is to get arrow up action in powershell to load previous command. This way, I can quickly just type make clean followed by arrow up to get history command from powershell make build. This used to work previously, but I have no idea what exactly changed. It seems that make calls bash and bash is interpreting my arrow up as escape sequence that gets sent to powershell without esc seqeunce.
I tried to insert into my .bashrc set keyseq-timeout either to 0, or some big value, nothing helped.
Also, this happens in powershell standalone, or even in cmd.
How to get it working as previously?
It works when you're calling from a Bash environment, such as WSL or Git Bash.
^[[A[1] is getting printed if you press the up-arrow while a command is still running, but the buffered keystroke does take effect after the command terminates; the behavior is the same in Git Bash, except that^[[Adoes not print.When calling from a native Windows shell, such as
cmd.exeor PowerShell, that shell does not receive the buffered keystroke; instead, it is handled by the terminal (console) itself.This is in effect a no-op: the cursor moves up one line in the terminal, but then the Windows-native shell regains control and prints its prompt string on the original line, followed by placing the cursor at the end.
I'm unclear on the exact reason, but I suspect it is related to the fact that two shells are involved, and that the buffered keystroke, due to the Bash shell having exited along with the command, isn't handled by Bash and also isn't passed to the outer, Windows-native shell, causing the terminal emulator to interpret it.
If you want to stick with using Bash as the shell in your Makefiles, the next section provides - imperfect - workarounds.
cmd.exeor PowerShell for shell commands, which involves both placing aSHELLstatement at the top - see this answer - and changing the actual shell commands to PowerShell commands.Workarounds with Bash as the Makefile shell:
If the aim is to simply recall the previous command and execute it right away, you can use PowerShell's
Invoke-Historycmdlet, whose built-in alias isr(presumably short for recall):Note: If you want to make the re-execution contingent on
make cleansignaling success, usemake clean && rin PowerShell (Core) 7+, andmake clean; if (0 -eq $LASTEXITCODE) { r }in Windows PowerShell. The same applies analogously to the other commands below.Of course, if you know ahead of time that
make buildis the next command you want to execute, simply make it part of the same command line; e.g.:If you fully want to emulate the up-arrow behavior, i.e. if you want to recall the previous command without instantly executing it, i.e. if you only want to place it in the command-line edit buffer:
First, define a helper function that simulates pressing the up-arrow key (twice, because at the time it executes the previous command is the penultimate one, because the current one has already been recorded):
Then call
uin lieu ofr:[1]
^[represents the ESC character, and the whole sequence -ESC [ A- is presumably what xterm-compatible terminal emulators emit when the up-arrow key is pressed. Many shells intercept this keystroke and interpret it to mean: recall the most recently submitted command and place it in the command-line edit buffer. In the absence of a shell, the cursor moves one line up from the current line.