terminal
terminal copied to clipboard
cmd: add environment variable to disable/enable 'Terminate batch job (Y/N)?' confirmation
(migrated from https://github.com/PowerShell/PowerShell/issues/7080 per @BrucePay's suggestion)
When I cancel a cmd
script with Ctrl C, the following dialog pops up:
Terminate batch job (Y/N)?
I understand why this exists, but I'd also like the option to disable it, so cancelling cancels immediately. Judging by Stack Overflow, I'm not the only one
So a request: could we have an environment variable to control this?
@paulcam206 as the cmd guru, he'll probably have more thoughts on the matter.
I really highly doubt that we could just add an env var to disable this, but it is an interactive-only scenario, so it might be possible...
Thanks for responding Mike! Any specific reason why checking a flag would be so difficult? Looking forward to seeing what @paulcam206 thinks.
Honestly, changing cmd.exe at all is a bit terrifying. You can't be sure who in the world is actually depending on that behavior for some reason or another.
it's possible that this could be done with something like a new setlocal
setting. however, we've not added one of these in a long time. that said, I'll file an item on our backlog to investigate :)
Ack @zadjii-msft - not proposing to change the default, so should only affect people who've explicitly set some very long string.
@paulcam206 thanks! I'm not sure about how setlocal
works - my real experience of cmd is launching cmd files from powershell). Would I still be able to do this in Powershell:
$env:TERMINATE_IMMEDIATELY='yes'
somefile.cmd
Then press Ctrl C
when I need to and have it work?
setlocal
doesn't behave the same way as an environment variable. It's a thing that would have to be put in at the top of the batch script that is somefile.cmd
as one of its first commands to adjust the way that one specific batch file is processed by the cmd.exe
engine. That's probably not suitable for your needs, but that's the way we have to go.
I don't think anyone is disagreeing with you, @mikemaccana, that this would be a five minute development change to read that environment variable and change the behavior of cmd.exe
. It absolutely would be a tiny development time.
It's just that from our experience, we know there's going to be a 3-24 month bug tail here where we get massive investigation callbacks by some billion dollar enterprise customer who for whatever reason was already using the environment variable we pick for another purpose. Their script that they give their rank-and-file folks will tell them to press Ctrl+C at some point in the batch script to do whatever happens, it will do something different, those people will notice the script doesn't match the computer anymore. They will then halt the production line and tell their supervisor. The supervisor tells some director. Their director comes screaming at their Microsoft enterprise support contract person that we've introduced a change to the OS that is costing them millions if not billions of dollars in shipments per month. Our directors at Microsoft then come bashing down our doors angry with us and make us fix it ASAP or revert it, we don't get to go home at 5pm to our families or friends because we're fixing it, we get stressed the heck out, we have to spin up servicing potentially for already shipped operating systems which is expensive and headache-causing...etc.
We can see this story coming a million miles away because it has happened before with other 'tiny' change we've been asked to make to cmd.exe
in the past few years.
I would just ask you to understand that cmd.exe
is very, very much in a maintenance mode and I just want to set expectations here. We maintain it, yes. We have a renewed interest in command-line development, yes. But our focuses are revolving around improving the terminal and platform itself and bringing modern, supported shells to be the best they can be on Windows. Paul will put this on the backlog of things that people want in cmd.exe
, yes. But it will sink to the bottom of the backlog because changing cmd.exe
is our worst nightmare as its compatibility story is among the heaviest of any piece of the operating system.
I would highly recommend that Gulp convert to using PowerShell scripts and that if such an issue exists with PowerShell, that we get their modern, supported, and better-engineered platform to support the scenario. I don't want you to sit around waiting for cmd.exe
to change this because it's really not going to happen faster than that script could be converted to ps1
and it fixed in PowerShell Core (if that's even a problem in that world.)
oh god I'm having ptsd flashbacks just reading that
yep
@All - @miniksa @zadjii-msft and @paulcam206 are not kidding - the unexpected impact of even the smallest change to Cmd has resulted in calamities, misfortune, lost-weekends and evenings, stress and unnecessary turmoil.
Cmd is in maintenance mode. It isn't being deprecated or removed - in fact, I doubt it'll EVER be removed from Windows, but do understand that Cmd is extremely fragile and difficult to change.
I keep saying it, and now that PowerShell is available almost everywhere - even Linux & macOS - it's more true than ever:
If you're writing Windows Command-Line scripts today, they should be PowerShell scripts wherever possible
Thanks @bitcrazed. I appreciate the testimony directly from the horse's mouth - I've submitted a PR to one of the many node projects that use cmd
scripts, with a .ps1
replacement. Hopefully it gets accepted and we start moving node onto a more supported scripting language.
It seems to me that cmd scripts are generally used in the place of exe symlinks and shebang scripts, which PowerShell is not a good replacement for - if you switch out yarn.cmd
for yarn.ps1
, that's fine if you're already in PowerShell, but if you're in cmd, or some other shell, or using ShellExecute
or some scripting language's equivalent, you have to write pwsh -c yarn
, so then why not get rid of the script altogether and do node yarn.js
?
For this type of thing, we're pretty much stuck with something in PATHEXT
, and I think cmd is the only console interpreter in there.
Powershell is just as good as cmd here. If you're calling yarn.js
from some other language of course you'd run node yarn.js
, whether yarn comes with yarn.cmd
or yarn.ps1
. The point is you can type yarn
from the command line (which in Windows is powershell) and it runs yarn, and when something goes wrong you don't have to debug something which isn't maintained anymore. I've replied on https://github.com/yarnpkg/yarn/pull/6093 with more info - it may be best to move the discussion there.
Well, relevant to this thread, adding the setlocal option is just as good and addresses my concerns also - then all the projects that use cmd scripts this way just add another line at the top.
It still requires projects to opt into this behavior, and it's not compatible with older versions of Windows (well, it's compatible, just ignored), but it seems like the best way to do this to me. Doesn't break any other cmd scripts assuming yarn
is a command, and I'd be happy replacing my hacked together exe launcher with these.
The point is you can type yarn from the command line (which in Windows is powershell)
With all the recent console improvements and WSL, I think there's a possibility of seeing alternate shells on Windows in the future. Cmd may be in maintenance mode, but people still use it too, so I'm not a huge fan of this assumption.
Personally I'd really like to see the setlocal option, regardless of how projects choose to handle this.
It seems to me that cmd scripts are generally used in the place of exe symlinks and shebang scripts, which PowerShell is not a good replacement for
It's true. For example, perl wraps all scripts installed from cpan with a few lines of batch code loading perl executable using its pl2bat
script.
setlocal
variant would be very helpful for perl because it would allow us to fix Terminate batch job (Y/N)?
issue by making pl2bat
add setlocal
line to scripts generated with this tool .
@bitcrazed But, executing PowerShell script is not enabled by default.
@parkovski An interesting idea would be using WSF/WSH files.
Any progress on this issue?
cmd.exe
is very, very much in a maintenance mode and I just want to set expectations here. We maintain it, yes. We have a renewed interest in command-line development, yes. But our focuses are revolving around improving the terminal and platform itself and bringing modern, supported shells to be the best they can be on Windows.
We're not going to make changes to cmd.exe to support this scenario.
cmd.exe
is very, very much in a maintenance mode and I just want to set expectations here. We maintain it, yes. We have a renewed interest in command-line development, yes. But our focuses are revolving around improving the terminal and platform itself and bringing modern, supported shells to be the best they can be on Windows.We're not going to make changes to cmd.exe to support this scenario.
Okay, I understand this. But, is there an unofficial / hack solution to this? I searched the web and only found someone patching binary to do this. Unfortunately, that only works for Windows XP to and Windows 7
Then I found another project, https://github.com/sgraham/cmdEx Only works for Windows 8.1 32bit
:(
Something replacing .cmd and .bat? PS1 is too complex and too slow.
发件人: Jack Works [email protected] 发送时间: Tuesday, April 2, 2019 10:06:41 PM 收件人: Microsoft/console 抄送: Renzhi Li; Comment 主题: Re: [Microsoft/console] cmd: add environment variable to disable/enable 'Terminate batch job (Y/N)?' confirmation (#217)
cmd.exe is very, very much in a maintenance mode and I just want to set expectations here. We maintain it, yes. We have a renewed interest in command-line development, yes. But our focuses are revolving around improving the terminal and platform itself and bringing modern, supported shells to be the best they can be on Windows.
We're not going to make changes to cmd.exe to support this scenario.
Okay, I understand this. But, is there an unofficial / hack solution to this? I searched the web and only found someone patching binary to do this. Unfortunately, that only works for Windows XP to and Windows 7
Then I found another project, https://github.com/sgraham/cmdExhttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fsgraham%2FcmdEx&data=02%7C01%7CRenzhi.Li%40microsoft.com%7Cea8b6c7e4ee14e5d780d08d6b7746eb7%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636898108031211694&sdata=Id%2FYm1klHq6nHjQY50Uph9FdTWHsGsTXRYOODmYox8s%3D&reserved=0 Only works for Windows 8.1 32bit
:(
― You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FMicrosoft%2Fconsole%2Fissues%2F217%23issuecomment-479012154&data=02%7C01%7CRenzhi.Li%40microsoft.com%7Cea8b6c7e4ee14e5d780d08d6b7746eb7%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636898108031211694&sdata=dVp4NGya3W6yH7NMFgg87lb38fhjj7r%2F%2Fmr3xTTwHuM%3D&reserved=0, or mute the threadhttps://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAAOp25uHVKve6DUbDGCsqYMg3lRvJlcDks5vc2PxgaJpZM4VGR0n&data=02%7C01%7CRenzhi.Li%40microsoft.com%7Cea8b6c7e4ee14e5d780d08d6b7746eb7%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636898108031221686&sdata=jVKSOX8R0tjLrlcqejdOgDPJ4pTVFg9FhuzSKS7fPAc%3D&reserved=0.
@Jack-Works, we are not in the business of developing or propagating unofficial hacks to our software. If you figure something out, more power to you. But we can't help you there.
@be5invis, I'm sure the Powershell team would be happy to accept your feedback and improve their product. They are the Microsoft team that has funding for the interactive shell space.
As everyone else says, the fix for this is moving from cmd
to ps1
. @bitcrazed mentioned he's going to publish a blog post recommending people do this a little while ago (since a lot of node folks etc are producing new cmd
scripts).
While we wait for peopel to start distributing ps1
scripts, the safest bet to handle leftover cmd
s is to etiher press Ctrl C twice or use something like Hyper's https://hyper.is/plugins/hyper-yes
I agree with the problem with using powershell here instead of cmd; which I agree would be ideal, except it's far too slow in its initialization time. Even more unfortunately the new pwsh is even slower to initialize. This is something I opened an issue about, but the situation is not likely to be improved https://github.com/PowerShell/PowerShell/issues/6443.
Startup latency: 466 ms POWERSHELL 42 ms CMD
500 ms is way too long for a script, hence I'm not sure the solution to use ps1 is actually reasonable.
Here's the script to test start up latency
> function time($block) {
$sw = [Diagnostics.Stopwatch]::StartNew()
&$block
$sw.Stop()
$sw.Elapsed
}
> time {powershell -NoProfile -c exit}
> time {cmd-NoProfile -c exit}
CMD.exe is not getting updated. I don't know how to stress that any further.
Sorry I should've been made it clear that I know that cmd.exe won't be updated. I wanted to highlight the issues with the powershell recommendation, compared to using cmd.exe, and that hopefully an another solution may exist.
@miniksa @musm @zadjii-msft
.PS1
's problem:
- PowerShell is still 10× times slower than CMD.
- Scripts are disabled by default!
From my view, the best solution for “.cmd
stubs” might be generating an EXE stub (like Shimmy), if it does not irrate anti-malware softwares. A code signature may reduce such false positives (sign the code part and put the command line pattern into the rest places.)
For UPDATE: It doesn't work. WSH starts the Node process in a new window.npm
, an interesting solution may be using .js
files directly and launch them with WSH -- and then forward it to the real .js
entry points.
I don't know all the details of this and would be curious to hear some more informed opinions, but:
- PE files (.exe) start with the "magic number"
MZ
. - Executable shell scripts with a shebang also have a two byte magic number,
#!
.
Is there any way to inform the loader that when the magic number is #!
, it will be passed to the interpreter specified in the rest of the line, like linux shebang files? As far as I can tell, this would solve all the issues regarding slow shell startup time (we bypass PowerShell and cmd altogether), the PATHEXT
issue that exists with .ps1
files, the pain point of trying to launch them from WSL, and any weird behavior caused by using cmd.exe for this purpose.
It also seems to me, although I'm certainly not an expert, that there wouldn't really be a security risk here, as a regular binary exe could do anything and more that a shebang script could, and if signing was enabled for these scripts, I can't see how they would be any different than any other exes.
@parkovski This wouldn't be safe at all since Windows has no equivalent of the execute bit (chmod +x).
Why not? .exe
is the execute bit. Totally open to corrections, but a shebang exe would be basically equivalent to a shim exe that just launches another process, without the overhead of actually loading a launcher process. All other security features that already apply to exes would still apply to this type; it's just a special form where the shebang line replaces the exe name, just as .bat
automatically invokes cmd.exe
, or a shim exe can "fork out" to another exe.
As in, what is the difference between these two:
- foo.exe:
#!node ....
- foo.exe: Invokes
node
with the text stored somewhere in the file that can be extracted with WinAPIs.
I don't see any difference, except that one is easily human creatable/editable, while the other requires a compiler.
Look at the scoop package manager's shims. They are a hack around this - an exe that loads a text file and launches it. I don't see how extending the exe could possibly be any more dangerous than what is already available.
Oh, I see -- you're not advocating allowing any file to be a shebang script. I can't speak to the can of worms that would open, nor do I ever think this would be considered but it's interesting to ponder nonetheless.