Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wt.exe] Add support for appending a commandline to a profile's commandline #5528

Closed
nbabanov opened this issue Apr 24, 2020 · 27 comments · Fixed by #15822
Closed

[wt.exe] Add support for appending a commandline to a profile's commandline #5528

nbabanov opened this issue Apr 24, 2020 · 27 comments · Fixed by #15822
Labels
Area-Commandline wt.exe's commandline arguments good first issue This is a fix that might be easier for someone to do as a first contribution Help Wanted We encourage anyone to jump in on these. In-PR This issue has a related PR Issue-Task It's a feature request, but it doesn't really need a major design. Needs-Tag-Fix Doesn't match tag requirements Product-Terminal The new Windows Terminal.
Milestone

Comments

@nbabanov
Copy link

Description of the new feature/enhancement

After the #5090 update it would be great if we could do something like this:

wt "yarn some-command"; split-pane -V -d ./some-dir "yarn some-other-command"

It would enable us to execute commands in the Windows Terminal sessions and it can be used as any normal console terminal right now.

@nbabanov nbabanov added the Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. label Apr 24, 2020
@ghost ghost added Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Needs-Tag-Fix Doesn't match tag requirements labels Apr 24, 2020
@zadjii-msft
Copy link
Member

Uh, that's literally how it's supposed to work now... This doc has some examples.

Are you seeing some sort of error when you try that? Are you running the commandline from cmd, powershell, pwsh, bash, something else?

@zadjii-msft zadjii-msft added Area-Commandline wt.exe's commandline arguments Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something Product-Terminal The new Windows Terminal. and removed Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. labels Apr 24, 2020
@nbabanov
Copy link
Author

nbabanov commented Apr 24, 2020

@zadjii-msft The examples you gave are for different terminal programs to be assigned to the different views.

My example with yarn was that yarn manager had to be executed with the default terminal profile, not that yarn itself is a terminal.

wt cmd "dir" -> WT window running a cmd instance and no dir command execution.
wt "dir" -> [error 0x80070002 when launching `dir']

My default terminal profile is using git bash, but I've tested it out also with cmd.

@ghost ghost added Needs-Attention The core contributors need to come back around and look at this ASAP. and removed Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something labels Apr 24, 2020
@zadjii-msft
Copy link
Member

zadjii-msft commented Apr 24, 2020

oh oh oh I think I see what's happening. yarn isn't a Windows executable, it's a WSL one, right? The commandline argument is just a Windows commandline to start, not "a commandline to run in the profile that's spawned".

You can also see this in the dir example you gave. dir is a "cmd intrinsic", which means it's a feature of cmd.exe itself, there's not a dir.exe that cmd spawns. So you can't just CreateProcess("dir",...), because there isn't a dir.exe to spawn. You need to launch cmd to be able to run dir. As a wt commandline, that'd be something like wt cmd /k dir.

So, for the yarn case, you'd probably want wt wsl yarn some-command

EDIT: Okay I'm seeing now the update to your post to include notes about "git bash". I'm not super familiar with how git bash works unfortunately, but I'd presume that you'd need to use the following commandline:

wt "C:/Program Files/Git/bin/bash.exe" yarn some-command

Here, I'm assuming that "C:/Program Files/Git/bin/bash.exe" yarn some-command will run yarn some-command in git bash. I don't know if that path is totally appropriate, or if bash.exe requires extra arguments to launch a child process appropriately.

@nbabanov
Copy link
Author

I've tested it. It works, but every time I have to enter the full path of the command line terminal, before passing commands to it. It would be great the fire up the default if none are present. :)

@zadjii-msft
Copy link
Member

So that gets complicated.

  • We can't really know if the thing that the user asked us to spawn was a shell or something else, so it doesn't really make sense for us to blindly send the commandline as input to executable spawned by the user's profile and assume that the process on the other end will appropriately treat it as a commandline and execute it.
  • It's also impossible for us to just append the provided commandline to the commandline of the user's profile. What if the user's profile is wsl ping (contrived example but gets the point across)? Then, a commandline of wsl ping yarn some-command would certainly not work.
  • It's also probably impossible for us to know if the commandline they've provided is a real executable or not. If we could, then we could maybe test the commandline, find that it doesn't work, then fall back to {profile.commandline} {commandline from args}. I'm sure there's another thread about this somewhere, but IIRC we determined that it's generally impossible to tell if a particular commandline will resolve to a process without just trying to start the process.

There's maybe room for us to add something like --appendCommandline [arguments...] that behaves the way you're expecting. For that reason, I'm gonna leave this issue open and tack it onto the commandline args megathread. I hate that name for it, so it'd probably need a proper spec review, but I don't hate the idea of it.

@zadjii-msft zadjii-msft added Issue-Task It's a feature request, but it doesn't really need a major design. and removed Needs-Attention The core contributors need to come back around and look at this ASAP. labels Apr 24, 2020
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label Apr 24, 2020
@zadjii-msft zadjii-msft added this to the Terminal Backlog milestone Apr 24, 2020
@zadjii-msft zadjii-msft changed the title Add support to execute commands when calling wt [wt.exe] Add support for appending a commandline to a profile's commandline Apr 24, 2020
@nbabanov
Copy link
Author

nbabanov commented Apr 24, 2020

Just an idea:
What if the unified way of starting a specific command line terminal is wt -p "Windows PowerShell" | cmd | <any-exe-in-PATH> | <path-to-exe>, if -p is not specified wt usese the default profile and all added arugments after that are run in the profile.

Your idea with --appendCommandline also sounds okay. Maybe you and your team would have to decide which scenario is more common/sensible to implement.

@DHowett-MSFT DHowett-MSFT removed the Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting label Apr 25, 2020
@Ruegen
Copy link

Ruegen commented Jun 14, 2020

I'd personally like to see support for adding command line arguments for the profile after launch. This way once a tab is launched we can have it so that it automatically executes a command in that terminal window.

@DHowett
Copy link
Member

DHowett commented Jun 14, 2020

@Ruegen cmd /k command1 && command; powershell -noexit -c command1 && command2; bash -c "command1; exec bash -l"

@Kif11
Copy link

Kif11 commented Jun 16, 2020

This seams to work for running command in a new open window.

wt ubuntu run "ls / && bash"

This will run Ubuntu WSL and then execute ls / and then leave bash interactive shell open. Without bash at the end it just exits.

@tihomir-kit
Copy link

tihomir-kit commented Jul 4, 2020

I've tested it. It works, but every time I have to enter the full path of the command line terminal, before passing commands to it. It would be great the fire up the default if none are present. :)

I believe the reason for this might be that "C:/Program Files/Git/bin/bash.exe" is used, but the user to use it has not been "logged in". What I mean by that is, take this for example. This is my GitBash profile:

      {
        "guid": "{00000000-0000-0000-0000-000000000001}",
        "acrylicOpacity": 0.9,
        "useAcrylic": true,
        "closeOnExit": true,
        "colorScheme": "Solarized Dark",
        "commandline": "\"%PROGRAMFILES%\\Git\\usr\\bin\\bash.exe\" --login -i -l",
        "cursorColor": "#FFFFFF",
        "cursorShape": "bar",
        "fontFace": "Consolas",
        "fontSize": 10,
        "historySize": 9001,
        "icon": "%PROGRAMFILES%\\Git\\mingw64\\share\\git\\git-for-windows.ico",
        "name": "GitBash",
        "padding": "15, 5, 10, 55",
        "snapOnInput": true,
        "startingDirectory": "%USERPROFILE%\\Desktop"
      },

Notice how it has --login -i -l. Without that, my bash profile is not loaded and as a result I don't have my aliases for example. And perhaps the same reason is causing something as simple as ls to fail.

image

Although, probably I'm totally off the ball on this one.

@grmlin
Copy link

grmlin commented Sep 7, 2020

It would be incredibly useful to open a Windows Terminal (wsl) profile from the commandline and run a command inside afterwards. Something like

wt -p Debian "cd ~/my-project & npm start"

I could create shortcuts to projects and stuff, start environments with a single click. I tried many different combinations of the wt command, but nothing worked. Or am I missing something?

Thanks for the help!

@zadjii-msft
Copy link
Member

@DennisBecker Can you not use wt.exe -- node.exe <whatever the args to node are>? That should spawn a new WT window, running node.exe <whatever the args to node are>

@patricknelson
Copy link

@tihomir-kit I was attempting the exact same thing. I'll elaborate on a fix since I landed here searching for a solution, too. Basically the goal was:

  • Use Windows Terminal to launch my default profile (e.g. Git's bash), which in my case already included the -l to login and run my .bash_profile with the aliases and stuff. Then...
  • Try to execute some arbitrary command now that my aliases and SSH agent are now available, etc.

The problem with this was that I was incorrectly assuming that the commandline in my profile would be executed (the path to bash.exe in your example above). In reality, you actually have to provide that command all over again and include the -c parameter to bash so it knows to also run that command.

The key is just repeating the path to bash.exe and then also ensuring you add bash's -c parameter. For example:

wt -p GitBash -- "%PROGRAMFILES%\Git\usr\bin\bash.exe" -i -l -c "COMMAND"

Breaking it down:

  1. wt -p GitBash --
    • Launches Windows Terminal with the "GitBash" profile. Everything after this is the command line to execute. Just set all your wt flags at/before this point.
  2. "%PROGRAMFILES%\Git\usr\bin\bash.exe" -i -l
    • Launch bash, with an interactive shell (-i) and telling it to login (-l), which runs your bash profile script, loads aliases, etc. Somewhat redundant since that's already defined in your commandline profile setting.
  3. -c "COMMAND"
    • Now that it's logged in, tells bash to run some arbitrary command within the scope of that shell.

@akaltar
Copy link

akaltar commented Jan 17, 2021

Following what @patricknelson wrote, if you have C:\Program Files\Git\bin on your PATH, you can simplify this further to:
wt bash -i -l -c "COMMAND"

eg.
wt bash -i -l -c "yarn start"

And you don't even need a custom profile.

@tihomir-kit
Copy link

tihomir-kit commented Feb 2, 2021

@patricknelson Thanks a lot, that did the trick!

@akaltar For some reason that doesn't work for me. I checked the C:\Program Files\Git\bin and bash indeed is in there. I also tried adding %PROGRAMFILES%\Git\usr\bin to my PATH but that didn't help either.

What I get is:

[process exited with code 1]

@tihomir-kit
Copy link

Hmm, now I ran into a different issue, is there a way to end the double dash? With that, I can run something, but I would like to chain a ; split-pane -V with another bash command to run after that.

@tihomir-kit
Copy link

Well this worked finally:

set bsh="%PROGRAMFILES%\Git\usr\bin\bash.exe"

wt ^
  -p GitBash -- "%bsh%" -i -l -c "alias1"; ^
  split-pane -V -- "%bsh%" -i -l -c "alias2"

I did it with a batch script instead of bash because bash complains about insufficient permissions when I try to run WT from it..

The last thing that would be nice to have is to be able to actually stop the command that was running and keep the pane. For example if an npm run start was running and you stop it with CTRL+C, the process will exit, but the pane will remain unusable.

@DHowett
Copy link
Member

DHowett commented Feb 2, 2021

You can set closeOnExit to never to make your panes stay open but remain unusable. 😄

@akaltar
Copy link

akaltar commented Feb 2, 2021

@tihomir-kit
You can use this:
bash -i -l -c "yarn start:local\;bash -i -l";
Eg just make sure that after whatever command you execute, execute bash again.
This needs a ; which needs to be escaped with / since it's in a bash script in a batch file

Also when adding the git bash path to your PATH, make sure it comes before any other bash executables. I had to move it up in the list quite a bit.

@ha7ilm
Copy link

ha7ilm commented May 23, 2022

(removed comment, sorry I didn't read the question properly)

@zadjii-msft
Copy link
Member

zadjii-msft commented Aug 24, 2022

I'm gonna make probably a 🌶️ take, but yank "spec needed" off this. A spec seems too heavy. I think we should just do this as

--appendCommandline: If specified, the [command...] parameter 
                     is appended to the profile's current commandline, 
                     rather than replacing it. 

so

wt new-tab -p Ubuntu --appendCommandline ping 8.8.8.8

would do what you'd expect. We can come up with a short form in the review, if we really need.

Should be trivial to add to AppCommandlineArgs::_addNewTerminalArgs and then evaluate in AppCommandlineArgs::_getNewTerminalArgs.

It's up to the user to make sure that their combination of chosen profile & --appendCommandline actually makes sense.

Note

Walkthrough

  • Add flag to AppCommandlineArgs::_addNewTerminalArgs
  • Evaluate the full commandline in AppCommandlineArgs::_getNewTerminalArgs.

@zadjii-msft zadjii-msft added Help Wanted We encourage anyone to jump in on these. good first issue This is a fix that might be easier for someone to do as a first contribution labels Aug 24, 2022
@nbabanov
Copy link
Author

@zadjii-msft I like your suggestion. It perfectly fits with my original intent.

@hanpuliu-charles
Copy link
Contributor

hanpuliu-charles commented Aug 7, 2023

When evaluating the full commandline in AppCommandlineArgs::_getNewTerminalArgs, should we fetch the chosen profile
's commandline and concatonate it with the argument, storing it in the NewTerminalArgs's commandline field? Do we need to first get the global shared settings, then the profile from the NewTerminalArg to get the commandline from the profile or is there a more optimal way to do this? Thanks!

@zadjii-msft
Copy link
Member

Oh, you bring up a very good point. Nowhere in AppCommandlineArgs does it know anything about the Profile itself. It's just stashing the commandline it found into the NewTerminalArgs, then letting TerminalSettings::CreateWithNewTerminalArgs actually reason about how to layer that with the profile.

Maybe it makes more sense then to add a boolean to NewTerminalArgs, that'll change how CreateWithNewTerminalArgs behaves.

In that case:

  • add a Boolean AppendCommandline to NewTerminalArgs in ActionArgs.idl (and in ActionArgs.h)
  • Use --appendCommandline to set that boolean
  • in CreateWithNewTerminalArgs, use that boolean to append the Commandline, instead of replacing it.

@microsoft-github-policy-service microsoft-github-policy-service bot added the In-PR This issue has a related PR label Aug 11, 2023
zadjii-msft pushed a commit that referenced this issue Aug 24, 2023
Added --appendCommandLine flag that when set, appends the command to the
preset command in the profile instead of replacing it.

Previously, there was no good way to launch wt while running a command
appended to the set command in the profile. Some uses include profiles
that are set to login or start an application.

Additional comments: Looking for a review, and expecting additional
changes that needs to be done. For example, I am not really sure on how
to include the the option's information in the CallForHelp() screen.
Also, would be great if someone could guide me on including tests for
this new feature. Thanks!

Closes #5528

---------

Co-authored-by: Charles Liu <hliu729@outlook.com>
@microsoft-github-policy-service microsoft-github-policy-service bot added the Needs-Tag-Fix Doesn't match tag requirements label Aug 24, 2023
@M43R
Copy link

M43R commented Oct 27, 2023

Add --appendCommandLine flag for appending to command

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Commandline wt.exe's commandline arguments good first issue This is a fix that might be easier for someone to do as a first contribution Help Wanted We encourage anyone to jump in on these. In-PR This issue has a related PR Issue-Task It's a feature request, but it doesn't really need a major design. Needs-Tag-Fix Doesn't match tag requirements Product-Terminal The new Windows Terminal.
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

16 participants