3

Cygwin's bash is often preferable to Windows' cmd command shell, so we use it to set up our environments before spawning a Windows shell. However, halting execution of a running process in this spawned shell with Ctrl-C kills boots the user back to the bash shell.

My attempted workaround:

source setupEnvironment.sh

restartCommand() {
  # Reset trap
  trap restartCommand SIGINT
  echo -e " === Restarting windows cmd prompt\n"
  cmd /k 
}

trap restartCommand SIGINT
echo -e " === Starting windows cmd prompt\n"
cmd /k

This approach only restarts cmd once. Subsequent Ctrl-C's are not caught. Is there a way to keep restarting the cmd process?

mklement0
  • 382,024
  • 64
  • 607
  • 775
tcdaniel
  • 203
  • 1
  • 2
  • 11
  • Curious why you can't do everything in bash itself, why do you need to start cmd at all? – Miserable Variable Jan 30 '13 at 21:37
  • @Miserable Variable: personally, I'm happy staying in bash. But others at work want the cmd prompt. So I compromised: I'll invoke cmd, but only after setting up the environment in bash (bash does everything better!). – tcdaniel Jan 30 '13 at 21:45

3 Answers3

2

Does it have to be in the same window? If not, I have had much better luck with

cygstart cmd

cmd starts in its own window; and only exit closes that window

Miserable Variable
  • 28,432
  • 15
  • 72
  • 133
  • Nice workaround. The extra window isn't ideal, but everything then works as expected. – tcdaniel Jan 30 '13 at 23:32
  • The cygstart options `--wait` might be useful here. – Miserable Variable Jan 30 '13 at 23:50
  • I tried that - but the process stays on in the background without the user knowing. Just an extra process and a couple MB of RAM, but when you rarely restart your PC, that could add up. – tcdaniel Jan 31 '13 at 03:10
  • Which process? Bash? How is `bash` started? Another alternative is for the bash process to exit after starting cmd using cygstart (without --wait). BTW even when you start cmd without cygstart the bash process stays in memory – Miserable Variable Jan 31 '13 at 03:16
  • Whoops, my last comment referred to `--hide`. This closed the window but the parent **process** stayed active. Trying `--wait` didn't seem to do anything useful either. Yes, the best solution for now is `cygstart cmd /K; exit`. What I didn't say was this bash prompt was actually started from a cmd prompt - so the bash prompt is effectively sandwiched between 2 cmd prompts, unknown to the user. So exiting bash doesn't exit the original cmd prompt. – tcdaniel Jan 31 '13 at 03:21
  • Oh hmmm. Given this scenario I think it is best if you set the environment in cmd itself :) Or perhaps create a .bat file using bash (change `export x=y` to `echo set x=y >> envvars.bat` and execute the generated bat file from cmd, where a called bat file can modify the caller's env – Miserable Variable Jan 31 '13 at 03:24
  • Haha - yeah, that's where I started, with 2 parallel scripts to setup a development environment (on Linux and Windows). There is significant overlap, so I combined them to reduce maintenance. Thanks for the help. – tcdaniel Jan 31 '13 at 03:36
1

Subsequent Ctrl-Cs aren't caught because your script exits due to reaching the end.

Chances are cmd will return error when you ctrl-c, in which case you could do

until cmd /k; do true; done

Otherwise, make your script loop, until ctrl-c isn't pressed:

trap restart=1 SIGINT
echo -e " === Starting windows cmd prompt\n"
restart=1
while (( restart )); do restart=0; cmd /k; done
that other guy
  • 116,971
  • 11
  • 170
  • 194
  • Thanks - both answers works reasonably well, and may be the best I can hope for. When cmd is in the middle of compiling, Ctrl-C still frequently boots back to bash though. Also, the cmd window sometimes locks up and may be closed only by End Process from Task Manager. – tcdaniel Jan 30 '13 at 23:25
1

To complement Miserable Variable's helpful answer with an explanation of why opening cmd.exe in its own console window is the best approach:

  • While you can try to work around the Ctrl-C issue as demonstrated in that other guy's answer, the behavior is not quite the same as in a regular cmd.exe console window: since a new instance of cmd.exe is created every time Ctrl-C is pressed, previous state is lost.

  • The Cygwin terminal (console window) uses the UTF-8 character encoding rather than the regular console window's encoding that is based on the (legacy) OEM code page, and the two are incompatible.

  • Curiously, staying in the Cygwin terminal causes cmd.exe to echo all interactively submitted commands (as you'd get in a batch file without @echo off).

To automatically close the Cygwin window when launching the cmd.exe console window, use
exec cygstart cmd.

Community
  • 1
  • 1
mklement0
  • 382,024
  • 64
  • 607
  • 775