Prevent powershell script arguments with asterisk from expanding into separate file names when passed to Java program [duplicate] - powershell

I wrote a program in Java that accepts input via command line arguments.
I get an input of two numbers and an operator from the command line.
To multiply two numbers, I have to give input as e.g. 5 3 *, but it's not working as written.
Why is it not accepting * from the command line?

That's because * is a shell wildcard: it has a special meaning to the shell, which expands it before passing it on to the command (in this case, java).
Since you need a literal *, you need to escape it from the shell. The exact way of escaping varies depending on your shell, but you can try:
java ProgramName 5 3 "*"
Or:
java ProgramName 5 3 \*
By the way, if you want to know what the shell does with the *, try printing the content of String[] args to your main method. You'll find that it will contain names of the files in your directory.
This can be handy if you need to pass some filenames as command line arguments.
See also
Wikipedia: glob
For example, if a directory contains two files, a.log and b.log then the command cat *.log will be expanded by the shell to cat a.log b.log
Wikipedia: Escape character
In Bourne shell (sh), the asterisk (*) and question mark (?) characters are wildcard characters expanded via globbing. Without a preceding escape character, an * will expand to the names of all files in the working directory that don't start with a period if and only if there are such files, otherwise * remains unexpanded. So to refer to a file literally called "*", the shell must be told not to interpret it in this way, by preceding it with a backslash (\).

Under MS WINDOWS not quite true: "java.exe" silently expands command line arguments with the wildcards
*
?
[abc]
, but only in the last component, so
a/*/*
does not work as you may expect.
It also ignores the entries "." and "..", but does honor other file names starting with ".".
To avoid misunderstandings: If I look at the command line of the running JAVA process with PROCEXP, I see the unexpanded args!
I found no way to work around this. In other words: As long as you have at least one file or directory in the current directory, "java Calc 3 * 7" will NOT work!
This is VERY ugly, and seems to always having been there in all JRE versions up to and including Java 8.
Does anybody have an idea how to disable Java's nasty command line expansion?

* has special meaning in shell interpreters. How to get a * literally is depending on what shell interpreter you are using. For Bash, you should put single quotes around the *, i.e. '*', instead of double quotes like "*".

Try surrounding the * with quotes like "*". The star is a reserved symbol on the command line.

Use single quotes:
java FooBar 5 3 '*'
This works with most of the popular shells (including bash and ksh).

Expanding on #Arno Unkrig's answer:
On Windows, some JVMs definitely do expand the "*" character, and it is not the shell expanding the path. You can confirm this by writing a small Java program that prints out the arguments:
public class TestArgs {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
System.out.println("Arg " + i + ": " + args[i]);
}
}
}
The good news is, there is a workaround! You can use #filename as an argument to JVM like this:
java #args.txt where args.txt is a text file that contains the arguments for each line. Example content:
TestArgs
*
This is equivalent to calling java with two arguments TestArgs and *. Most importantly, * is not expanded when it is included using the #filename method. I was able to find the details from this page.

Related

match string pattern by certain characters but exclude combinations of those characters

I have the following sample string:
'-Dparam="x" -f hello-world.txt bye1.txt foo_bar.txt -Dparam2="y"'
I am trying to use RegEx (PowerShell, .NET flavor) to extract the filenames hello-world.txt, bye1.txt, and foo_bar.txt.
The real use case could have any number of -D parameters, and the -f <filenames> argument could appear in any position between these other parameters. I can't easily use something like split to extract it as the delimiter positioning could change, so I thought RegEx might be a good proposition here.
My attempt is something like this in PowerShell (can be opened on any Windows system and copy pasted into it):
'-Dparam="x" -f hello-world.txt bye1.txt foo_bar.txt -Dparam2="y"' -replace '^.* -f ([a-zA-Z0-9_.\s-]+).*$','$1'
Desired output:
hello-world.txt bye1.txt foo_bar.txt
My problem is that I either only take hello-world.txt, or I get hello-world.txt all the way to the end of the string or next = symbol (as in the example above).
I am having trouble expressing that \s is allowed, since I need to capture multiple space-delimited filenames, but that the combination of \s-[a-zA-Z] is not allowed, as that indicates the start of the next argument.

sqlplus - No characters are allowed after a here-string header but before the end of the line

I'm trying to use sqlplus to do an Oracle query for the first time in a PowerShell script. I get this error message:
At line:1 char:73
+ ... user/pw#RRRPRD.company.net:1521/RRRPRDC #"C:\Users\ ...
+ ~
No characters are allowed after a here-string header but before the end of the line.
It seems to be pointing to the C: after #". Any ideas? I seem to be doing what is at this example. I get the same error when I try to do echoargs of the connection info.
This is my powershell code I am testing at the command line since it hangs forever running the program:
sqlplus user/pw#RRRPRD.company.net:1521/RRRPRDC #"C:\Users\me\Documents\2021\temp endToEnd\short.sql"
This is using powershell 5.1. Any ideas? I see here string header, but since I am following the example that was accepted in the link for sqlplus above, it's unclear to me what's wrong with it.
Replace
#"C:\Users\me\Documents\2021\temp endToEnd\short.sql"
with any of the following:
`#"C:\Users\me\Documents\2021\temp endToEnd\short.sql"
"#C:\Users\me\Documents\2021\temp endToEnd\short.sql"
'#C:\Users\me\Documents\2021\temp endToEnd\short.sql'
Note: Using a verbatim (single-quoted) string ('...') is arguably the best choice here, given that the path contains no variable references; if it did, a expandable (double-quoted) string ("...") would be equired.
All variations end up passing the following string verbatim to sqlplus, which I presume is your intent:
#C:\Users\me\Documents\2021\temp endToEnd\short.sql
Presumably, you're trying to pass # as a verbatim part of an argument to sqlplus - a common convention among CLIs is to use #<file-path> to request that argument data be taken from a file rather than using the argument value itself.
However, unlike in other shells, # is a metacharacter in PowerShell that serves a variety of purposes.
Thus, a # that should be a verbatim character at the start of an argument must either be escaped (with `) or part of a quoted string, as shown above. See the conceptual about_Special_Characters help topic.
If an unescaped argument-initial # is followed by " or ', PowerShell thinks you're trying to create a here-string, which has special, multi-line syntax requirements; the error message indicates that they're not met.

How do I deal with space bar when escaping double quote character in Power-Shell

I am able to escape double quote character in PowerShell however when this includes strings with space escaping does not work correctly.
For example:
I can translate the following ADUC to powershell
Name in ADUC: cn="Jim"
In powershell: "cn=\`"Jim\`""
How do I handle/escape the space between Jim and Carter as below ?
Name in ADUC: cn="Jim Carter"
In powershell: "cn=\`"Jim Carter\`""
The output I get is Jim, the space and string Carter are lost.
PowerShell has hidden re-quoting logic when arguments are passed to external utilities.
What you're seeing is bug in Windows PowerShell (that has since been fixed in PowerShell Core):
In short, "cn=\`"Jim Carter\`"" is passed to an external executable as cn=\"Jim Beam\", which unexpectedly turns into two arguments - note how the argument is not double-quoted as a whole, even though it needs to be.
Workarounds:
As part of a distinguished name in Active Directory, component values (such as Jim Beam for field cn) usually do not need double-quoting, even if they contain spaces. Therefore, perhaps the following will work (depending on the behavior of the executable you're invoking).
someExternalTool.exe "cn=Jim Beam"
If you do need the executable to ultimately see string literal cn="Jim Beam", you must use --%, the stop-parsing symbol:
someExternalTool.exe --% "cn=\"Jim Beam\""
If you want the executable to see cn=\"Jim Beam\", i.e., with the " chars. \-escaped, use someExternalTool.exe --% "cn=\\\"Jim Beam\\\""
Note that use of --% then precludes the use of PowerShell variables as part of the same command.
In PowerShell Core, your original argument, "cn=\`"Jim Carter\`"" is passed as "cn=\"Jim Carter\"" - i.e. with the necessary double-quoting as a whole - so the problem with the unexpected argument splitting wouldn't arise, and your target program would see cn="Jim Beam" after performing its own argument parsing.
If you need the target program to see cn=\"Jim Beam\", you'd have to use "cn=\\\`"Jim Beam\\\`"" - or, using single-quoting, 'cn=\\\"Jim Beam\\\"'
As an aside: The need to \-escape " chars. to pass to external programs - in addition to PowerShell's own escaping - should itself be considered a bug, but it's a longstanding one that probably won't be fixed so as to maintain backward compatibility: see this GitHub issue.

Passing file path with spaces and forward slashes as argument to TCL command

I have a TCL script that is run by Libero using a file path provided as an argument to open a project. The file path is C:\Users\me\Documents\FPGA projects\file.prjx
I am running the script according to Libero TCL Reference Guide (pages 51 - 52) to run the script on the command line. On page 47, the doc outlines how to work with filenames with spaces; using braces or in the case where it is used as an argument use double quotes.
The command I am trying to execute is:
Path\to\libero SCRIPT:export.tcl SCRIPT_ARGS:""C:\Users\me\Documents\FPGA projects\file.prjx""
The outer set of double quotes is to follow the syntax outlined in page 52 of the document for providing arguments and the inner set of double quotes is to handle the white space in the first argument. I had expected $argv 0 to be C:\Users\me\Documents\FPGA projects\file.prjx, but instead $argv 0 is actually C:\Users\me\Documents\FPGA.
I added a print statement to the script to print $argv:
puts $argv
This gives a result of C:\Users\me\Documents\FPGA so the rest of the file path is not being interpreted as even being a second argument.
My assumption is that the conventions outlined in the document are just standard TCL conventions for providing a file path containing forward slashes and spaces as an argument. I have not been able to find an example of passing a similarly formatted argument in TCL. Any ideas?
I'm not sure it's the same issue but, having MagicSplat tclsh.exe and wish.exe linked to *.tcl and *.tk files in Windows (7 to 11), calling scripts this way:
processDIR.tcl "c:\My directory\subdir"
evals arguments only till first space, becoming "c:\My" BUT calling scripts like this:
tclsh.exe processDIR.tcl "c:\My directory\subdir"
trespasses complete argument.
Could you give it a try?

Xcode breakpoint shell command argument length

Trying to pass a large string to a shell script using a breakpoint in Xcode
let value = Array(repeating: "a", count: 1500).joined()
let string = "{\"key\": \"\(value)\"}"
Unfortunately, the string is being truncated. Is this limitation documented and can it be overcome?
It's been nearly a year since you asked this, and I'm not sure if it will solve your question, but I've recently had a similar problem so thought I'd share my solution.
I had two issues:
LLDB was truncating any arguments to my shell script (and string variables printed in the console using po foo) to 1023 characters. I believe this is the issue to which your question relates.
Xcode was incorrectly confusing a comma , in my string as a separator for multiple arguments (e.g. passing foo, bar, and baz as arguments to the script wouldn't work correctly if any of the variables contained a , as Xcode would try to create another argument).
So, firstly, the LLDB issue...
It seems that by default LLDB has a limit on the character length that it will print to the console (or pass to a shell script via a breakpoint argument) of around 1023 characters. You can easily change this to something larger by setting another breakpoint before the breakpoint that uses your variable and running (lldb) set set target.max-string-summary-length 10000 in the console. This can be a bit annoying so I created a ~/.lldbinit file and placed set set target.max-string-summary-length 10000 in there instead so I don't have to keep setting it in the console.
Secondly, the comma issue...
Inside the Edit breakpoint... menu that you provided a screenshot of above there is the option to not only provide a path to a script but to also provide arguments. I can see from your question that you provided the argument #string#. For my script, I was passing multiple arguments, which Xcode allows you to do using a comma separated list, e.g. #foo#, #bar#, #baz#. Each of these arguments was a string.
I noticed that sometimes one or more of these strings would truncate if they contained a comma: ,.
So the string:
{ "num_friends" : "7" }
would be passed to my script as expected. But the string:
{ "num_friends" : "7", "num_deleted_friends" : "1" }
would truncate and would be passed to my script as two separate arguments. It seems that Xcode would split any string with a , even when entered using #string#.
I validated this in my script by simply using something like:
for var in "$#"
do
echo "$var"
echo "===="
done
Where $# expands to contain each argument. From this I could see that #string# was being correctly passed to my script but separated as multiple arguments wherever there was a ,. So if #string# contained a comma my script would print:
#"{ \"num_friends\" : \"7\"
====
\"num_deleted_friends\" : \"1\" }"
instead of what I expected which was:
#"{ \"num_friends\" : \"7\", \"num_deleted_friends\" : \"1\" }"
So it seems like it might be a bug in how Xcode passes strings inside # expressions in the breakpoint editor window.
My crude solution has been to just replace any commas with another character and then replace them back again inside my script. There's probably a better way to do this but I don't require it for my needs.