Failed to process input: The parameter must begin with a / or - - docker

I am running a Dockerfile but every time it stops at one point.
RUN powershell %windir%\system32\inetsrv\appcmd.exe set config /section:system.webServer/handlers /+"[name='Test',path='Test.cgi',verb='*',modules="IsapiModule",scriptProcessor="c:\Test.dll",resourceType="Unspecified", preCondition="bitness64"]"
Failed to process input: The parameter 'verb=*' must begin with a / or -
I am struggling for hours. What could be the reason?

You're trying to invoke appcmd.exe via PowerShell (powershell.exe), even though the appcmd.exe command line doesn't require the features of that shell - it seems to be composed of literal strings only.
Your use of %windir% implies that your Dockerfile uses the default shell on Windows, namely cmd.exe
Therefore, you should be able to formulate your appcmd.exe command line as you would submit it from a cmd.exe session:
RUN %windir%\system32\inetsrv\appcmd.exe set config /section:system.webServer/handlers /+[name='Test',path='Test.cgi',verb='*',modules='IsapiModule',scriptProcessor='c:\Test.dll',resourceType='Unspecified',preCondition='bitness64']
Note:
All quoting in the remainder of the argument that starts with /+ now uses only '...', for consistency; since no argument-internal " chars. are therefore in play, the need to escape them goes away.
No spaces are allowed in the remainder of the argument.
As for what you tried:
When you use the -Command / -c PowerShell CLI parameter (which is implied in the absence of -File), " characters to be passed through as part of the PowerShell command must be escaped as \".
See this answer for an explanation.
Since your /+ argument also contains embedded " chars., as part of the argument, you would have to escape them twice, namely as `\" (sic)

Related

Powershell Docker Command Doesn't Work Like Bat File

I'm trying to create a script that starts a docker container and mounts a local folder that contains spaces in the name. I can get it to work fine when I run a *.bat file with the docker run command:
docker run -p 8081:8081 -v "C:\Test Folder With Blanks":/zzz myimage jupyter lab --notebook-dir=/zzz--ip=0.0.0.0 --port=8081 --allow-root
But when I try to do the same in a Powershell script file, I get an error:
$CMD = 'docker run -p 8081:8081 -v "C:\Test Folder With Blanks":/zzz myimage jupyter lab --notebook-dir=/zzz--ip=0.0.0.0 --port=8081 --allow-root'
Invoke-Expression $CMD
docker: invalid reference format.
See 'docker run --help'.
I'm on Win10 and running Powershell in Visual Studio Code IDE.
Thanks for ideas.
First, the obligatory warning: Unless you have a command line stored as a single string somewhere and you either fully control or trust the content of the string, Invoke-Expression should generally be avoided.
You're seeing an inconsistency in how PowerShell treats compound tokens composed of directly concatenated quoted and unquoted parts.
Specifically, argument "C:\Test Folder With Blanks":/zzz is unexpectedly broken in two, i.e passed as two arguments.
The workaround is to quote the entire argument, i.e.
"C:\Test Folder With Blanks:/zzz"
Note: I'm assuming that docker doesn't actually require partial quoting in its arguments, which it shouldn't; however, there are high-profile CLIs on Windows that do, notably msiexec.
Alternatively, use an expression enclosed in (...) to compose your string; e.g.
("C:\Test Folder With Blanks" + ':/zzz')
There's no good reason to do so in this case, but it could be helpful if you need string interpolation in one part of your string ("..."), but not in another ('...').
General caveats:
Compared to cmd.exe and also POSIX-compatible shells such as bash, PowerShell has several additional metacharacters, notably # (at the start of a token), { / }, and ;. Therefore, you cannot always expect command lines written for these shells to work as-is in PowerShell.
As of PowerShell 7.2.2, passing arguments to external programs (such as docker) is fundamentally broken with respect to arguments that have embedded " characters and empty-string arguments - see this answer.
The general pattern of the inconsistency, as of PowerShell 7.2.2, is as follows:
If an argument:
starts with a quoted token - whether single- ('...') or double-quoted ("...") -
and has additional characters directly following the closing quote,
the first such character starts a separate argument.
E.g. "foo":bar / "foo"=bar / "foo"'bar' are passed as separate arguments foo and :bar / foo and =bar / foo and bar, respectively.
In other words:
You cannot compose a single string argument from a mix of quoted and unquoted / differently quoted tokens if the first token is quoted.
Conversely, it does work if the first token is unquoted, including an unquoted simple variable reference such as $HOME.
# OK: First token is unquoted.
PS> cmd /c echo foo"bar"'baz'last
foobarbazlast
# !! BROKEN: First token is quoted.
# !! Because each successive token is quoted too,
# !! each becomes its own argument.
PS> cmd /c echo 'foo'"bar"'baz'last
foo bar baz last
GitHub issue #6467 discusses this inconsistency; however, it has been closed, because the behavior is - surprisingly - considered by design.
This does not happen if the first token is unquoted; however, there are related bugs that start with unquoted tokens that similarly break arguments in two, related to their looking like named arguments to PowerShell (which is a PowerShell concept that doesn't apply when calling external programs):
GitHub issue #11646: an argument such as -foo=1,2 breaks parsing.
GitHub issue #6291: an argument such as -foo=bar.baz is broken in two at the (first) .

Using Revision Variable in Docker Build Step

Trying to use the $(Rev:.r) variable in my docker build steps (version 1.*) for tagging and it doesn't seem to work. I always get
2019-01-14T21:42:24.4149933Z ##[error]invalid argument
"wp/imagename:0.6$(rev:.r)" for "-t, --tag" flag: invalid reference
format 2019-01-14T21:42:24.4160700Z ##[error]See 'docker build
--help'. 2019-01-14T21:42:24.4274219Z ##[error]/usr/bin/docker failed with return code: 125
No variable substitution seems to be happening and it looks like it's running it through with the Qualify image name option and lower-casing the R. Can anyone else use the $(Rev:.r) variable?
Doesn't matter where I try using that variable, i can use it in the Image Name option or the Arguments option and it gives me the same error.
-t wp/imagename:0.6$(Rev:.r)
You can't get just "the revision number" without parsing, it is not stored as a separate field somewhere. The $(Rev:.r) portion instructs Azure DevOps to come up with the first number that makes the build number unique (and, in that specific example, put a dot in front of it). Only the final build number is available.
At workaround, add a the $(Rev:.r) in the end of your build number (if it not there). add a PowerShell script task (you can do it inline PowerShell) before the Docker task and put this code:
$buildNumber = $Env:BUILD_BUILDNUMBER
$revision= $buildNumber.Substring($buildNumber.LastIndexOf('.') + 1)
Write-Host ("##vso[task.setvariable variable=revision;]$revision")
In your docker use the $revision variable:
-t wp/imagename:0.6$(revision)
I've only been able to get it to be recognized in the Build number format section under options.
If you are using this like a build number, why not just set the build number there instead and then reference using $(Build.BuildNumber)?

How to pass an argument which starts with $ to ant from cygwin terminal?

I am running an ant command from Cygwin terminal where I am signing my exe.
I am running a command similar to
ant -Dpassword=$abcde
Here $abcde is my password but when I run an echo, it shows the password as blank.
How can I pass $ as part of my argument so ant can process it?
In a Unix shell, the $ sign is used to identify a shell variable. To prevent parameter expansion due to it being treated as a variable, you need to either:
escape it (by prepending a backslash)
or wrap it in single quotes (quoting removes the special meaning of certain characters such as $)
Either of the following should work:
ant -Dpassword=\$abcde
ant -Dpassword='$abcde'
Edit: It seems that ant treats the dollar sign as a special character. Assuming that a backslash can be used by ant for escaping special characters, both the backslash and the dollar character should be passed on to ant by the shell:
ant -Dpassword='\$abcde'

Ubuntu Cmake: Parse error in command line argument [duplicate]

-D CMAKE_C_COMPILER is what I use to choose my compiler. However, if I have CMake options that are turned on/off like USEIPHONEFLAG, I need to do -DUSEIPHONEFLAG=1, -D USEIPHONEFLAG=1 does not work. I was wondering how the space after -D works in CMake.
CMake's command line parsing is not very consistent or robust unfortunately.
This issue is probably down to the order in which you pass the arguments.
Internally, CMake iterates over the command line arguments twice. The first time it's looking for non-cache arguments and skips any beginning with -D. Any that don't fit into the list of proper args are assumed to be the path to the CMakeLists.txt file (or the directory, or the CMakeCache.txt).
It's assuming that there will be only one path passed, and does nothing to validate that assumption. Herein lies the problem. If you've passed -D Foo=1, then -D is seen as a complete argument and is skipped, and Foo=1 is seen as a path.
On the second iteration through the args, it now grabs the values given via -D, but on this run it correctly handles spaces after the -D. So it understands that -D Foo=1 is setting Foo to 1.
So, the position of the path in your command line is all-important here.
cmake -D Foo=1 MyProject/CMakeLists.txt # --> Works
cmake MyProject/CMakeLists.txt -D Foo=1 # --> Fails
To complicate things further, you can wrap the space in quotes and have CMake parse it, but the variable name then includes the space and is unusable in the CMakeLists file.
cmake MyProject/CMakeLists.txt "-D Foo=1" # --> Defines the unusable var ${ Foo}
Another inconsistency is that other command line flags work with or without a space (e.g. -G), and others require a space (e.g. -E).
My own advice would be to always avoid adding a space after the flag unless it's required. I guess always passing the path last would help too, although that shouldn't be required if you don't add extra spaces.

How to parse variables from a parameter file in a K Shell script

I have a shell script I wish to read parameters from an external file, to get files via FTP:
parameters.txt:
FTP_SERVER=ftpserer.foo.org
FTP_USER_NAME=user
FTP_USER_PASSWORD=pass
FTP_SOURCE_DIRECTORY="/data/secondary/"
FTP_FILE_NAME="core.lst"
I cannot find how to read these variables into my FTP_GET.sh script, I have tried using read but it just echoed the vars and doesn't store them as required.
Assuming that 'K Shell' is Korn Shell, and that you are willing to trust the contents of the file, then you can use the dot command '.':
. parameters.txt
This will read and interpret the file in the current shell. The feature has been in Bourne shell since it was first released, and is in the Korn Shell and Bash too. The C Shell equivalent is source, which Bash also treats as a synonym for dot.
If you don't trust the file then you can read the values with read, validate the values, and then use eval to set the variables:
while read line
do
# Check - which is HARD!
eval $line
done

Resources