Comments (7)
@jhowardmsft - I believe this is a known issue but can you confirm?
from docker-powershell.
Oh. I misread. I believe the issue is that you cant pass the params to docker like that. The REST API is a bit different from the CLI in that it does some fancy parsing. You really need to execute:
Start-ContainerProcess -ContainerIdOrName first -Command @("powershell", "(dir c:)")
@swernli - Can you confirm that you always have to separate args in PS execution?
from docker-powershell.
So -Command parameter always expects string[2] where first element is executable and second one is parameter?
from docker-powershell.
@swernli - Bump for the holidays
from docker-powershell.
@jterry75 @artisticcheese This one is a bit weird, so bear with me. The short explanation is that docker expects the command parameter in their JSON to be the array of tokenized strings for the command you want to execute, so it can be an array of any length. What you are doing above works, since the items in the parens can be considered one token. Another command that has several tokens, such as "cmd /c echo test" could be represented as "cmd","/c echo test"
or "cmd","/c","echo","test"
and I believe either would work. Alternatively, when using the cmdlet, you could forgo the explicit -Command
and just make sure your command is the last parameter provided, and then just type it normally on the commandline (with proper escapes for any powershell characters like "-"). For example:
> Run-ContainerImage microsoft/nanoserver powershell echo test
This method has some big conveniences and some annoying quirks, and understanding them requires the longer explanation...
Cmdlets that include the Command parameter have it decorated with ValueFromRemainingArguments = true
as you can see at https://github.com/Microsoft/Docker-PowerShell/blob/master/src/Docker.PowerShell/Cmdlets/StartContainerProcess.cs#L20. What this means is that if the -Command
parameter name is not explicitly provided, then powershell will just populate the command from whatever elements are left at the end of the cmdlet invocation after processing all other parameters. This is as close as we could get to the behavior of the docker CLI, which relies on the tokenizing of the shell it executes in for translating input from the user into a string array. If we had made the Command parameter a single string instead of string[]
then we would have to tokenize it ourselves, and that would be a pretty complex bit of code. Unfortunately, ValueFromRemainingArguments uses powershell’s cmdline logic, which means extra escape characters may have to used to differentiate between elements you want powershell to evaluate and elements that should be passed along as-is to the parameter. Your use of parenthesis above is a good example, in fact. If I try to use the remaining arguments trick for that, I get an error:
PS > Run-ContainerImage microsoft/nanoserver -Isolation HyperV -RemoveAutomatically powershell (dir c:\)
Invoke-ContainerImage : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Command'.
Specified method is not supported.
At line:1 char:1
+ Run-ContainerImage microsoft/nanoserver -Isolation HyperV -RemoveAuto ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-ContainerImage], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Docker.PowerShell.Cmdlets.InvokeContainerImage
This is because powershell, when it sees the (dir c:\)
, actually evaluates it and tries to insert the resulting array of objects as an item into the Command string array. What you really want is powershell to ignore the parenthesis and just pass them through as tokens instead of evaluating them, so you have to escape them using a backtick:
PS C:\Windows\system32> Run-ContainerImage microsoft/nanoserver -Isolation HyperV -RemoveAutomatically powershell `(dir c:\`)
This will produce the correct result. The same would have to be done with the "-" and "$" characters to prevent the host powershell window from trying to interpret them.
It's not pretty, but it's the closest we could get to something that would allow callers to write container commands without having to manually tokenize the command in a string array themselves.
from docker-powershell.
Damn, I hoped going to powershell route on managing lifecycle of container instead of relying on ugly "docker" commands will prevent what you just described above happening. But seems this UNIX born theater followed to powershell wrapper as well.
from docker-powershell.
Yeah, it's definitely annoying. If there were some generic tokenize function in .NET somewhere, we might have been able to use that and simplify this, but we couldn't find anything. And tokenizing input is an annoying problem, especially when you factor in how many special characters may or may not change the behavior and the fact that which characters are considered special changes between shells and platforms. So both docker CLI and cmdlet take the same approach: punt the problem to the shell itself, and let the user figure out how to say what they mean.
I've run into the same problem when executing cmd commands from within powershell and vice versa; in general, interop between multiple shell paradigms is not well solved, and containers bring that to the forefront due to the desire to specify a command within another command.
from docker-powershell.
Related Issues (20)
- config.Volumes are incorrectly processed HOT 1
- ShouldContinue & ShouldProcess attribute missing in the Cmdlets HOT 7
- New-ContainerImage missing option to specify network for build process HOT 1
- Get-ContainerImage returns Size property value as 0 HOT 1
- How to use PortBindings property of HostConfig? HOT 8
- Getting "Unknown URL scheme" error if docker is running on alternative protocol HOT 2
- Please add port mappings to default output of Get-Container cmdlet HOT 1
- Enhancment request to output history of the image HOT 1
- Mounted folder appears empty using Docker-PowerShell; fine with 'docker' HOT 1
- --build-args HOT 4
- get-container simplified query for Running or Stopped containers HOT 1
- We need a Find-ContainerImage for docker search HOT 1
- Cannot install Azure modules on Docker-PowerShell HOT 1
- Get-ContainerDetail Should return isolation type HOT 1
- v6.0.0-beta.3 release of PowerShellCore breaks module HOT 2
- Could not download reference symbols in local VS Code using docker
- Cannot restart a container
- powershell containers on docker hub can't be referenced by powershell version
- Name conflict with module already in PSGallery HOT 1
- Is this module dead HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from docker-powershell.