Ant execute a command - ant

I use Silk4J and in my build, I have to start the agent. The command I use is:
<exec spawn="true" executable="${env.OPEN_AGENT_HOME}/agent/openAgent.exe" />
It gives me this error
The ' characters around the executable and arguments are not part of the command.
Do I need to change it?

The message doesn't signify an error.
When the -v, -verbose, -d, or -debug option is given to Ant, the <exec> task outputs the command it is executing along with the message:
[exec] Current OS is Windows 7
[exec] Executing 'cmd' with arguments:
[exec] '/c'
[exec] '#for %a in (C:\src\ant\ant-dir-file-local) do #echo %~ta'
[exec]
[exec] The ' characters around the executable and arguments are
[exec] not part of the command.
[exec] 10/23/2013 02:36 AM
Breaking down the above example...
[exec] Executing 'cmd' with arguments:
^ ^
[exec] '/c'
^ ^
[exec] '#for %a in (C:\src\ant\ant-dir-file-local) do #echo %~ta'
^ ^
In this case, the single quotes (') above each ^ aren't part of the command. Ant wraps the executable name and each argument with single quotes to make it clear what is part of the command and what isn't. Ant does this to help users debug their Ant scripts when <exec> doesn't behave as expected. The message is purely informational.

It is good practice to wrap logged entries in single quotes so that if an entry is empty you can still see it, for example:
No password for user ''
Otherwise you would see:
No password for user
which is misleading.
In this case it only informs you that the quotes are only there for this reason and not part of the logged data. I think the sentence is slightly confusing because of the negative form 'are not part of the command' which looks like there is a problem...

It is purely informative. It is there to indicate that the apostrophe (') symbol you see above is not actually within the command that has been used.
It just "quotes" the string tokens you used in your command.
Example:
[exec] Current OS is Windows 10
[exec] Output redirected to property: git.timestamp
[exec] Executing 'cmd.exe' with arguments:
[exec] '/c'
[exec] 'git'
[exec] 'show'
[exec] '-s'
[exec] '--format=%ct'
[exec]
[exec] The ' characters around the executable and arguments are
[exec] not part of the command.
This indicates that you used /c git show -s --format=%ct inside cmd, and you can see that from the '/c', 'git' tokens. It just tells you to ignore the ' symbol. What it actually used is the git, show, -ss, etc. tokens in a chain, forming a full command.

This is fallible information for ant. Please note, that this error will result in a returned status code of "1", exiting your build as failed. It is not merely "purely informative" as the previous poster has stated. This part of the java invoked Runtime.exec() methods which ant implements. Overrides include the parameters (String command, args[]), and also (String cmdLine).

Related

Why can't ld called from MSYS find (existing static) library when arguments are read from a response #file containing backslashes?

This is basically the same issue as in mingw ld cannot find some library which is exist in the search path, MinGW linker can't find MPICH2 libraries - and I'm aware that there are heaps of posts on StackOverflow regarding the issue of static and dynamic linking with MinGW - but I couldn't find anything that explains how I can troubleshoot.
I am building a project with a huge linker command like (via g++) on MinGW, in a MSYS2 shell (git-bash.exe). The process fails with, among others:
/z/path/to/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lssl
I add -Wl,--verbose to the g++ linker call (to be passed to ld), and I can see for the -L/z/path/to/libs/openssl/lib/mingw -lssl:
...
attempt to open /z/path/to/libs/openssl/lib/mingw/libssl.a failed
...
/z/path/to/libs/openssl/lib/mingw/ssl.dll failed
attempt to open /z/path/to/libs/openssl/lib/mingw\libssl.a failed
...
But this is weird, because the file exists?
$ file /z/path/to/libs/openssl/lib/mingw/libssl.a
/z/path/to/libs/openssl/lib/mingw/libssl.a: current ar archive
(... and it was built with the same compiler on the same machine)?
Weirdly, once it attempts to open with forward slash .../libssl.a, once with backslash ...\libssl.a - but at least the first path checks out in a bash shell, as shown above?
It gets even worse if I try to specify -l:libssl.a -- or if I specify -L/z/path/to/libs/openssl/lib/mingw -Wl,-Bstatic -lssl -- instead; then all attempts to open are with a backslash:
...
attempt to open /z/path/to/scripts/other/build/openssl/build/mingw/lib\libssl.a failed
attempt to open /z/path/to/libs/openssl/lib/mingw\libssl.a failed
...
To top it all off, if I look it up manually through the command line using ld, it is found ?!:
$ ld -L/z/path/to/libs/openssl/lib/mingw -lssl --verbose
attempt to open Z:/path/to/libs/openssl/lib/mingw/libssl.dll.a failed
attempt to open Z:/path/to/libs/openssl/lib/mingw/ssl.dll.a failed
attempt to open Z:/path/to/libs/openssl/lib/mingw/libssl.a succeeded
Does anyone have an idea why this happens, and how can I get ld to finally find these libraries? Or rather - how can I troubleshoot, and understand why these libraries are not found, when they exist at the paths where ld tries to open them?
OK, found something more - not sure if this is a bug; but my problem is that I'm actually reading arguments from a file (otherwise I get g++: Argument list too long). So, to simulate that:
$ echo " -Wl,--verbose -L/z/path/to/libs/openssl/lib/mingw -lssl -lcrypto " > tmcd3
$ g++ #tcmd3 2>&1 | grep succeeded | grep ssl
# nothing
$ g++ `cat tcmd3` 2>&1 | grep succeeded | grep ssl
attempt to open Z:/path/to/libs/openssl/lib/mingw/libssl.a succeeded
attempt to open Z:/path/to/libs/openssl/lib/mingw/libcrypto.a succeeded
... it turns out, if the very same arguments are fed on the command line, then static library lookup succeeds - but if the arguments are read from file through the # at-sign, then static library lookup fails?! Unfortunately, I cannot use on my actual project, since even with cat, I'd still get g++: Argument list too long ... So how can I fix this?
MSYS has special handling of directories as arguments when they are used in the shell. This translates e.g. /<drive_letter>/blabla to the proper Windows style paths. This is to accomodate Unix programs that don't handle Z: style directory root.
What you see here is that MSYS isn't performing this interpretation for string read from a file. When you think about it, it's very logical, but as you have experienced first-hand, also sometimes annoying.
Long story short: don't put Unix style paths in files with command arguments. Instead, pass them through e.g. cygpath -w, which works in MSYS2 (which should be the MSYS that Git for Windows 2+ comes with).
Ok, with some more experiments, I noticed that:
-L/z/path/to/libs/openssl/lib/mingw, the Unix path specification, tends to fail - while if we specify the same, except starting with a Windows drive letter, that is:
-LZ:/path/to/libs/openssl/lib/mingw, then things work - also from an arguments file with # at-sign:
$ echo " -Wl,--verbose -LZ:/path/to/libs/openssl/lib/mingw -lssl -lcrypto " > tmcd3
$ g++ #tcmd3 2>&1 | grep succeeded | grep ssl
attempt to open Z:/path/to/libs/openssl/lib/mingw/libssl.a succeeded
attempt to open Z:/path/to/libs/openssl/lib/mingw/libcrypto.a succeeded
I guess, since the shell is MSYS2/git-bash.exe, entering full POSIX paths on the shell with /z/... is not a problem, because the shell will convert them - but in a file, there is nothing to convert them, so we must use Windows/MingW convention to specify them...

ANT: Use "," in <arg> without expansion to multiple arguments

The following ANT exec tag does not behave as expected.
<exec executable="c:\scratch\test.cmd">
<arg value="A,B,C"/>
</exec>
When executed, I would expect this to call text.cmd with 1 argument. However, the arg is being expanded to three separate arguments.
As per the Manual, value is supposed to pass the contents as a single argument, however, it is passed as three (one for each component of the string separated by a comma).
I tried replacing the command "," with a semicolon (;) but this does not work either. It appears as if arg's value attribute parses the supplied string as if it were a path, which it is not.
Anyone know how to the "A,B,C" to pass as one argument?
For the sake of completeness, my test.cmd file is this:
#echo off
echo Arg1: %1
echo Arg2: %2
echo Arg3: %3
echo Arg4: %4
echo Arg5: %5
echo Arg6: %6
echo Arg7: %7
echo Arg8: %8
echo Arg9: %9
and the output of the ant build is:
[exec] Arg1: A
[exec] Arg2: B
[exec] Arg3: C
[exec] Arg4:
[exec] Arg5:
[exec] Arg6:
[exec] Arg7:
[exec] Arg8:
[exec] Arg9:
Issue has been resolved. I was so focused on the issue being in ant, that I didn't take the time to test how DOS like command lines interpret the command-line arguments.
from Window command line, I ran test.cmd a,c,b and see that the command argument was split, therefore, the issue is not related to ant. so now I just need to figure out how to force ANT to quote the arguments.
Try:
<exec executable="c:\scratch\test.cmd">
<arg line="A,B,C"/>
</exec>
See ant manual for description of how arguments work.

Ant Command Line help: iisvdir

I'm trying to execute iisvdir from an ant script to clean and create a virtual directory before I compile my .net app in Visual Studio. I am running into a couple of strange errors one one build server, but another is running the script without any problem.
<exec dir="${SYSTEM32}" executable="cscript" failonerror="true">
<arg line='iisvdir.vbs /create "Default Web Site" ${RS_VIRTUAL_DIR} "${env.WORKSPACE}"'/>
</exec>
Results in:
[exec] Microsoft (R) Windows Script Host Version 5.6
[exec] Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
[exec]
[exec] Input Error: Can not find script file "c:\windows\system32\iisvdir.vbs".
And then
<exec dir="${SYSTEM32}" executable="cmd" failonerror="true">
<arg line='cscript iisvdir.vbs /create "Default Web Site" ${RS_VIRTUAL_DIR} "${env.WORKSPACE}"'/>
</exec>
Results in
[exec] 'reate' is not recognized as an internal or external command,
[exec] operable program or batch file.
Can someone help me figure out what might be wrong?
Is iisvdir.vbs where you say it is?
To get CMD.EXE to run a command, you need to use the /C switch.
For example:
cmd.exe echo Hello
...ignores the parameters and runs another interactive command prompt as a subshell.
cmd.exe /c echo Hello
...runs the "echo Hello" statement and returns immediately. Note: You can use /K if you want cmd.exe to continue running interactively after running the statement (not usually a good idea in a build script).
Your command:
cmd.exe cscript iisvdir.vbs /create etc.
...is getting parsed as if you'd really said:
cmd.exe /c reat etc.
This is because cmd.exe has (as with most MS command line tools) freaky command line parsing.
Update: Is this a 64-bit OS? If Ant is a 32-bit task, then it'll actually (silently) be looking in C:\Windows\SysWOW64 for cscript.exe and iisvdir.vbs. Are they there? If not, you should use C:\Windows\SysNative. In a 32-bit task, this is aliased to the real C:\Windows\System32 directory.
I don't know if it's the cause of your problems but I notice that you are using a single quote (') for <arg line='. All the examples I've seen use a double quote (") I know you are enclosing items with spaces in double quotes so it may be necessary to escape them out? Perhaps moving the code into a batch file which you can test before running via Ant?
Not sure if this will help but could point you in the right direction.

Windows Server 2003 call to secedit within a batch script generates "C:\Program" on system reboot

In executing
secedit /configure /db %~1\tomcat.sdb" /cfg %~1\2003.inf" /log %~1\dtomcat.log" /quiet
where
%~1 == C:\Program Files\myDirectory\mySubDirectory\mySuperSubDirectory
a file titled "C:\Program" is generated and within the file is the output for calling
secedit /?
I am curious as to why this is occuring because it makes it quite difficult to start certain services after an installation of a new product, for instance a PostGres windows service.
You appear to be missing quotes in a couple of places:
secedit /configure /db "%~1\tomcat.sdb" /cfg "%~1\2003.inf" /log "%~1\dtomcat.log" /quiet
^ ^ ^
You need to enclose the pathname in quotes:
"C:\Program Files\myDirectory\mySubDirectory\mySuperSubDirectory"
The space in "Program Files" is treated as a delimiter.

EXEC args (value) with quotes on linux from Ant script

bash shell:
./mimic_cmd "startDaemon()"
Corresponding Ant code:
<exec failonerror="true" executable="/bin/mimic_cmd">
<arg value='"startDaemon()"' />
</exec>
Does the Ant code exactly represent the above command at the bash shell? Based on the debug info, it looks like it:
[exec] Executing '/bin/mimic_cmd' with arguments:
[exec] '"startDaemon()"'
[exec]
[exec] The ' characters around the executable and arguments are
[exec] not part of the command.
Execute:Java13CommandLauncher: Executing '/bin/mimic_cmd' with arguments:
'"startDaemon()"'
The ' characters around the executable and arguments are not part of the command.
However, the Ant code returns and exit code of 1 while the Bash shell command returns 0.
Toggling vmlauncher doesn't help, and paths are all correct.
The same Ant code works on windows with the resulting debug output:
[exec] Executing 'C:\bin\mimic_cmd' with arguments:
[exec] '"startDaemon()"'
[exec]
[exec] The ' characters around the executable and arguments are
[exec] not part of the command.
Execute:Java13CommandLauncher: Executing 'C:\bin\mimic_cmd' with arguments:
'"startDaemon()"'
The ' characters around the executable and arguments are not part of the command.
Can you tell us what mimic_cmd is? (Is it an ELF executable, is it a script -- and if so, what is its contents?)
You don't need nor want the double-quotes inside your ANT XML attributes (incidentally, for it to be well-formed XML you should have written them as " not ", but that changes nothing with respect to this discussion) unless your executable expects them. The corresponding ANT code for either of the following (100% equivalent) shell command lines:
./mimic_cmd "startDaemon()"
./mimic_cmd 'startDaemon()'
./mimic_cmd startDaemon\(\)
./mimic_cmd startDaemon"()"
./mimic_cmd startDaemon'()'
...actually is:
<exec failonerror="true" executable="/bin/mimic_cmd">
<arg value="startDaemon()" />
</exec>
...or, for illustrative purposes:
<!-- spawn a shell with your original command line -->
<exec failonerror="true" executable="/bin/sh">
<arg value="-c" />
<arg value="/bin/mimic_cmd "startDaemon()"" />
</exec>
Why that is so is longwinded to explain; suffices to say that, in your specific case, the only time when you'd have to use double quotes would be when ultimately issuing the command via a *nix shell (either interactively or as part of another script or programatically via the execing of sh -c), and only in order for that shell not to think that the round parens () have special meaning. By the time the shell would in turn spawn mimic_cmd it would have already stripped the double quotes (and substituted backslash-escaped sequences etc. -- see how a *nix shell parses its command line) ANT does not run your command via the shell but rather executes it directly, so in this case mimic_cmd finds itself with a bunch of double quotes on its hand which it apparently doesn't know how to handle.
You essentially have to think of it as replacing all forms of shell quoting and escaping with XML escaping and breaing down into <arg/> tags.
Windows' CMD.EXE is special in the sense that, unline *nix shells, it does minimal parsing (and generally does not care about double quotes in program arguments), leaving it up to the program to figure out what you meant by quoting. (This is actually a hard limitation of Windows' CreateProcess which does not have the notion of argv[], leaving it up to each program to intepret lpCommandLine in whichever way it sees fit; some will get rid of the quotes for you, but that behaviour is extremely inconsistent, e.g. issue echo "bla" on the CMD.EXE prompt to see what CMD.EXE's builtins think about quoting.) Again, in your case the round parens () have no meaning for CMD.EXE so you don't need them even when typing the command at a command prompt. As for ANT, on Windows as on *nix platforms, it spwans mimic_cmd via CreateProcess not CMD.EXE so you don't really want to quote anything.

Resources