I'd like to put some Scala scripts into a batch file. If you just print the arguments, the canonical way would be like this:
::#!
#echo off
scala %0 %*
goto :eof
::!#
args foreach println
(This actually calls another batch script, scala.bat from the bin-directory of Scala). If I try to pass an argument containing parentheses to it, the windows command line interpreter complains with a syntax error:
printargs.bat "foo(bar)baz"
Strangely, if I create a scala file printargs.scala containing just args foreach println, this works correctly:
scala printargs.scala "foo(bar)baz"
So I assume this is not a bug in scala.bat. But what can I do?
Update: the actual error occurs in the following line in scala.bat:
set _ARGS=%*
with the error message
baz was unexpected at this time
If I change scala.bat that it does not use a local variable but use %* directly, it works correctly. So I filed a bug-report. The question remains if there is a workaround for this problem until the bug is fixed.
This bug does not occur in scala 2.8.1.final.
I would suggest using that version instead.
I don't think this has anything to do with Scala.. I'm currently having the same problem with passing an argument which contains parentheses into a grails command. Apparently this is a problem with the windows shell, have tried escaping the characters "(" but that does not work :/
Related
I've got a very simple rust program but its not doing quite what I'd expect. Running on Windows, using a powershell prompt, I can do the following to display the path:
echo "%PATH%"
and I have a simple Rust program with:
Command::new("echo")
.arg("%PATH%")
.spawn()
.expect("ls command failed to start");
The command will launch and run, but it outputs:
%PATH%
instead of the path contents, like I'd expect. Other commands which don't use special characters seem to work as expected, so I suspect its related to handling them but I don't see a way in Rust to make the command any more primitive than it already is.
I've tried various formatting but it either fails to run the command or does the same.
I also tried using $env:path, but this always fails to run from Rust with a cannot find the path specified error.
Are there any suggestions for handling this? I could write the contents to a file and run the file instead, but running these types of commands from other languages directly works fine so I think it should work from Rust as well.
Thanks!
Update:
Managed to get the expected results from by using:
let out = Command::new("cmd")
.arg("/C")
.arg("echo %PATH%")
.spawn()
.expect("ls command failed to start");
}
I think the question got interpreted a bit differently, as getting the path was just an example of a larger issue I was seeing. Updating with the above solved my larger issue as well.
As the comment by French says: Spawning the process does not include the Powershell-environment, which would expand %PATH% to it's actual content before launching the process.
You need to get the content of PATH via std::env yourself or lookup the Powershell documentation on how to launch a subprocess inside a powershell-session.
As others have mentioned, it's not the special characters, it's the fact that those special characters are interpreted by powershell before the "echo" program runs at all.
Using https://doc.rust-lang.org/cargo/reference/environment-variables.html as a reference for how to look up environment variables, try something like this:
use std::env;
fn main() {
let cur_path = env::var("PATH").unwrap();
println!("Environment is: {}", cur_path);
}
You can try this here: https://play.rust-lang.org/
You can then feed cur_path into your "Command::new" if you wish. The trick is that powershell substitutes that argument BEFORE launching echo, which you may not have known, whereas when you execute the echo program directly, you have to do that substitution yourself.
In Python you are not obliged to use a file, you can specify -c "..." and gives the Python commands to the Python interpreter via a string on the command line.
Can I achieve the same result with vbscript?
I've seen solutions that need you to use a batch script,
But what if I am on a system with zero writing permissions?
Following the answer from #Syberdoor, I can run this:
mshta vbscript:Execute("dim result:result=InputBox(""message"",""title"",""input"")(window.close):echo result")
but it still doesn't print the result in the console.
There is one trick you can possibly use and that is mshta.exe.
You can execute code like this:
mshta vbscript:Execute("<your code here, delimit lines with : (colon)>:close")
This is of course a fantasticly insane hack and on a system where you are not even allowed to create a file I am not sure if mshta.exe would be allowed.
Maybe you can also find additional inspiration from this thread (the mshta solution is also posted there). Although mostly batch related it is imo a great compendium of several really crazy ways to fool windows into executing vbs code.
No, the interpreters shipped with Windows (wscript.exe and cscript.exe) don't support that. If you can't create a file anywhere you're out of luck. You need some kind of wrapper script to transform the argument into something that VBScript interpreters can execute.
The naïve approach would be to create a VBScript with an ExecuteGlobal statement like this:
With WScript.Arguments.Named
If .Exists("c") Then ExecuteGlobal .Item("c")
End With
However, that won't work correctly, because double quotes aren't preserved in the arguments. If you ran the above script like this:
C:\> vbsrunner.vbs /c:"WScript.Echo "foo""
it would effectively execute the statement WScript.Echo foo instead of WScript.Echo "foo", and I was unable to find a way to escape nested double quotes so that they're preserved in the argument.
What will work is a batch script that writes the argument to a temporary file, and then executes that file with a VBScript interpreter:
#echo off
setlocal
set "tempfile=%TEMP%\%RANDOM%.vbs"
>"%tempfile%" echo.%~1
cscript.exe //NoLogo "%tempfile%"
del /q "%tempfile%"
That way you can run VBScript statements on the command line like this:
C:\> vbsrunner.cmd "WScript.Echo "foo" : WScript.Echo "bar""
foo
bar
If you wanted to replicate Python's interactive mode you could use my vbsh, but that would still require the ability to create a file somewhere.
I'm running this command on a batch file:
for %I in (*.txt *.doc) do copy %I c:\test2
...and it keeps returning:
I was unexpected at this time.
What is the cause of this error?
If you're running within a batch/cmd file, you need to double the % markers:
for %%i in (*.txt *.doc) do copy %%i c:\test2
The single % variant only works from the command line.
If being run from a batch file, variables need to be denoted with two percent signs, like %%I, only from the command line you use one
I ran across a case where I was getting this error from a file that was named *.cmd. The error arose when I tried to access the first argument to the batch command:
if %1 EQU ""
Once I put quotes around the symbol for the first argument, the warning message went away:
if "%1" EQU ""
Not a direct answer to the question, but if you encounter this message in any program, batch command, etc. then it's most likely related to your PATH containing " characters.
For instance, in Atom editor I was getting the message in the settings view.
"\"GNU was unexpected at this time
This was due to a different program putting in my PATH the following entry
...;C:\"Program Files"\"GNU ARM Embedded;..."
Because of that, the antislash character is read as escaped by some programs, which causes issues because then it's not a pathname delimiter but a simple character.
The solution for me was to remove those " from the PATH, and everything worked fine.
...;C:\Program Files\GNU ARM Embedded;...
PS: I have a doubt whether or not this can impact the original program (GNU ARM Embedded in this case) that maybe does not support spaces in pathnames. If somebody with more insight can clarify in the comments, I will update my post.
Hope this helps
I've got a Windows batch script issue that I'm bashing my head against (no pun intended). The problematic script looks like this:
if defined _OLD_VIRTUAL_PATH (
set PATH=%_OLD_VIRTUAL_PATH%
)
When I run it and _OLD_VIRTUAL_PATH is set I get:
\Microsoft was unexpected at this time.
_OLD_VIRTUAL_PATH is a variable that was originally set from PATH and it contains spaces - I'm pretty sure that's the problem. But what's the solution? It runs successfully if I enclose it in quotes, but I don't think the entire value of the PATH variable is supposed to be in quotes.
Your problem here are not the spaces but rather a closing parenthesis. You are probably running a 64-bit system where the Program Files directory for 32-bit applications is Program Files (x86). In a parenthesized block in a batch file, the closing parenthesis ends the block, so the rest of the line causes a syntax error.
You have two ways to fix this:
1) Put the complete set argument in quotes. This causes the closing paren to not be recognized as end of block:
if defined _OLD_VIRTUAL_PATH (
set "PATH=%_OLD_VIRTUAL_PATH%"
)
2) Don't use a block:
if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH%
Well - I never knew about the defined operation in cmd scripts until just now...
Your script seems to work fine for me - which line exactly is producing the error?
You can also try:
if not "%_OLD_VIRTUAL_PATH%" == "" (
set PATH=%_OLD_VIRTUAL_PATH%
)
And believe me, if you're coming into Windows cmd scripting expecting it to be anything like what you have in bash, your head will be very much in pain, very soon. You might want to look into using some other scripting language (PowerShell, Python, PERL - anything) if cmd scripting isn't an absolute requirement. the biggest thing (maybe the only thing) that cmd scripting has going for it is that it's already installed on every Windows box.
I am trying to use doxygen to generate documentation for some matlab classes I have written. I am using the doxygen-matlab package, which includes a perl script to kludge matlab .m files into c++ style commented files, so that doxygen can read them.
In my doxyfile, I have set (according to the instructions)
FILTER_PATTERNS = *m=C:/doxygenMatlab/m2cpp.pl
However, when the code runs, rather than running the script on the input files, it appears to just open the script using whatever the default windows setting for .pl is.
IE, if I associate .pl with notepad, the script is opened by notepad once for each input file doxygen is trying to parse. If I associate .pl with perl.exe, the script runs and throws the no argument error
Argument must contain filename -1 at C:\doxygenMatlab\m2cpp.pl line 4.
The doxygen documentation says
Doxygen will invoke the filter program by executing (via popen()) the command <filter> <input-file>
So I am wondering if there is some problem with popen() and windows that I could fix.
Could you try the workarounds I posted on the Matlab File Exchange regarding the doxygen package ?
Set the following variables in the Doxyfile :
INPUT_FILTER=perl m2cpp.pl
FILE_PATTERNS=*.m
If it doesn't work you should try to install ActivePerl : with this version of perl, everything is working fine.
I tried to reproduce the error using the Windows command prompt ("cmd") and noticed the following:
If you call "perl m2cpp.pl" you get error -1 because you did not specify a m-file to be translated into a cpp-file.
If you call "perl m2cpp.pl mfile" and the path of mfile contains spaces, you get error 1.
After I moved the mfile into a location which does not contain spaces, I got the desired output.
Now back to Doxygen. I tried what you suggested, Fabrice, without any luck. I read the doxygen help and found out that the INPUT_FILTER variable is only read and used if FILTER_PATTERNS is empty.
Therefore, I now use INPUT_FILTER = "C:\Programme\MATLAB\R2009a\sys\perl\win32\bin\perl U:\doxygen_matlab\m2cpp.pl" and an empty FILTER_PATTERNS variable. With this configuration, you can even leave the PERL_PATH variable empty. Moreover, there seems to be no issues with file names that contain spaces.
Unfortunately, all files are parsed with the above configuration, not only m-files. However, setting FILTER_PATTERNS to something like *.m=C:\Programme\MATLAB\R2009a\sys\perl\win32\bin\perl U:\doxygen_matlab\m2cpp.pl does not work because doxygen automatically adds the name of the filtered mfile and interprets the command as perl "m2cpp.pl mfile". Of course, the file "m2cpp.pl mfile" does not exist, because these are two files.
Maybe you can find a solution to this problem. In the meantime, I suggest the workaround above and that you keep your C-files away from the folder that contains the m-files.
write a simple batch file, e.g. mfilter.bat, which takes one argument from command line:
C:\Programme\MATLAB\R2009a\sys\perl\win32\bin\perl U:\doxygen_matlab\m2cpp.pl %1
Change setting in Doxyfile:
FILTER_PATTERNS = *.m=mfile.bat
This did it for me (on a Windows platform)
I think I solved this problem : it came from a bad association between .pl and the program to execute (maybe due to a bad installation of the perl shipped whith Matlab ?).
To correct this, you should change the association for the .pl files : in a Windows command prompt ("cmd"), just type de 2 following lines :
assoc .pl=PerlScript
ftype PerlScript=C:\Program Files\MATLAB\R20xx\sys\perl\win32\bin\perl.exe %1 %*
(the old installation forgot the %* at the end, the arguments were not passed to the m2cpp.pl script).
And then everything should be fine with the FILTER_PATTERNS set the usual way, for example FILTER_PATTERN=*m=C:\DoxygenMatlbab\m2cpp.pl
Could you tell me if this fixed your problem ?
According to the Doxygen forums, there is a difference in behavior between using INPUT_FILTER and FILTER_PATTERNS.
I found that if I do some extra (escaped) quoting, I can get FILTER_PATTERNS to work. For example, instead of:
FILTER_PATTERNS = "*.m=sed -e 's|%%|//!|'"
Try:
FILTER_PATTERNS = "*.m=\"sed -e 's|%%|//!|'\""
(All of my experimentation was done with doxygen version 1.8.6)