1

On Windows 10, I want to show an xterm window on my PC that runs on my server using ssh into the server.

For this I have created a Windows command script, as a file with .cmd extension, with the entire script as:

echo Before time: %TIME%
start /B ssh mysrv "xterm -T mysrv -display mypc:0.0"
echo After time: %TIME%

When running the cmd script through File Explorer, by double clicking on it, it creates the xterm window on my PC. There is no Windows shortcut, or similar, involved. However, a Windows command (cmd) terminal window is also left open, besides the xterm window. Both the messages "Before time:" and "After time:" are show in the Windows terminal window, with a time difference of at most 0.01 s, so they appear immediately.

If I change the xterm to a command that returns immediately, like date, or if I entirely remove the line with start ..., then the script finishes immediately, and no Windows command terminal is left.

I can manually close the Windows command terminal window by clicking the ‘X’, and the xterm window is left open and operational.  If I close the xterm window, then the Windows command terminal window is closed automatically.

However, it is rather annoying to get that extra useless Windows command terminal window.

The script is run on a clean Windows 10 installation, where there has been no manual modifications to the registry. For that reason, the suggestions in question I messed with my registry, now I need to change it back have not been attempted.

How can I create a Windows command script that runs the command ssh mysrv … and then terminates the script, without leaving the Windows command terminal window open?

8
  • Try adding the exit command at the end of the script.
    – harrymc
    Commented Dec 28, 2022 at 15:20
  • @harrymc: Adding exit did not fix the problem; the Windows command terminal window is still left.
    – EquipDev
    Commented Dec 28, 2022 at 15:56
  • A .bat file should not stay after execution. Please execute the solution in the duplicate link and reboot. If this doesn't help, let me know and I will reinstate your question.
    – harrymc
    Commented Dec 28, 2022 at 15:59
  • I’m not sure it matters, but please clarify: (1) Do you have those commands in a file with the .bat extension? (2) Is that the entire script? (3) Are you running it by navigating to the directory where it is and double-clicking on it?  Or is it on the Desktop? (4) Is a shortcut involved? (5) What happens if you do the same thing with a .bat file that contains only echo commands, but no ssh?  Or one that runs ssh without xterm, e.g., ssh mysrv "date >> mylogfile"? … (Cont’d) Commented Dec 29, 2022 at 0:46
  • 1
    Thank you. (1) FYI, a cleaner way to display the time in a CMD script is echo %TIME% (case insensitive). (2) It occurs to me now that ssh mysrv "sleep 60" would be another interesting test — does the CMD window exit immediately, or after a minute? (3) It seems to me that I’ve seen this problem, or something like it, before — the parent CMD window persists because a child process (even one started by the start command) is holding a resource (e.g., a network connection) open — but I can’t recall any details.  But I see that the question has been reopened, so maybe you’ll get some help now. Commented Dec 29, 2022 at 7:55

2 Answers 2

1

Windows automatically opens a console window for any executable that's marked as a "console executable" when compiled. The Conhost window isn't only hosting your cmd.exe script – it is also hosting the ssh.exe process (which is compiled as a "console" executable just like cmd.exe), and will remain as long as any console process is using it.

(This is rather different from the Unix model where the OS doesn't distinguish between console and non-console executables at all, so a terminal host such as xterm needs to be started manually.)

The API does allow starting console executables with the console hidden, but there's no option to do this through cmd.exe. A common alternative is to start ssh.exe through VBScript or Python, as Windows comes with a non-console "wscript.exe" VBScript host (and similarly Python comes with a non-console "pythonw.exe").

Example silentssh.vbs in VBScript:

Set wshell = CreateObject("WScript.Shell")
' Parameters: Run <command>, <show_window>, <wait_until_exit>
wshell.Run "ssh.exe /whatever", 0, 1
Set wshell = Nothing
1
  • Thanks, using the VBScript worked :-)
    – EquipDev
    Commented Dec 29, 2022 at 10:00
1

Solution 1

I don’t have ssh to test with, but I tried to simulate it, and I came up with this kludgy work-around:

EquipDev1.cmd:

start /min EquipDev2

EquipDev2.cmd:

rem Put your long-running command, e.g.,
    start /B ssh mysrv "xterm -T mysrv -display mypc:0.0"
rem here.

Double-click on EquipDev1.cmd.  As usual, it will open in a new, visible CMD window.  Then it will start EquipDev2.cmd in a new, minimized CMD window.  Then the EquipDev1.cmd script will end and its window will go away.  The EquipDev2.cmd “window” will persist until the ssh command terminates, but it’ll be minimized, so you’ll see it only if you look at the Taskbar.

Solution 2

(Totally untested.) Try start /B ssh mysrv "xterm -T mysrv -display mypc:0.0 &",  i.e., add an ampersand (&) at the end.  This should / might cause your shell on mysrv to run xterm as an asynchronous process, so the shell won’t wait for it to finish.  So the shell will exit immediately, and therefore so will your ssh, and so (hopefully) the CMD window will go away.

Note that some shells have the same problem as what you’re seeing with Windows / CMD — the shell might persist as long as a child process is alive, even if it was run asynchronously.  If you look around, you will find tricks for defeating that; e.g., nohup and disown.

1
  • Thanks for the suggestions. Solution 1: Still leaves the additional Windows command terminal window. Solution 2: The ampersand in executed xterm did not change anything.
    – EquipDev
    Commented Dec 29, 2022 at 9:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .