I am working with a Java program that calls an external batch file and passes in an array of commands. I have a loop in the batch file that looks like this:
set paramCount=0
for %%x in (%*) do (
set /A paramCount+=1
set list[!paramCount!]=%%x
)
The parameters are a bunch of directories, stored as strings, like this:
String[] commands = {"cmd.exe",
"/C",
"C:\Users\user\Documents",
"C:\Users\user\Pictures",
"C:\Users\user\Videos"}
As you can see, my for loop is supposed to loop through the list of the arguments passed to the batch file (%*) and emulate an array within the script (Since the first two elements in the command array are used to start the command process, that only leaves the directories to be looped through). The program was working just fine until the other day, when I suddenly started getting an error saying the following:
Environment variable list[ not defined
I had not made any changes to the batch file at all and it seemed to stop working for no reason. In case it's necessary information, I'm using a process builder to run the process:
ProcessBuilder pb = new ProcessBuilder(commands);
Process p = pb.start();
Supposedly using this syntax for an array in a batch file is okay, so I'm not sure why it doesn't accept it. I appreciate any help you can provide in this matter. I've run into a lot of roadblocks with this program, and while I've been able to solve 90% of them, the remaining 10% have begun to drive me crazy! Thanks!
EDIT:
I have re-written the loop and added in some echo commands to make debugging easier. When I run the batch file, though, nothing prints to the screen as a result of the echo but I still get the same error:
#echo off
setlocal enableDelayedExpansion
set paramCount=0
for %%x in (%*) do (
echo !paramCount!
echo %%x
set list[!paramCount!]=%%x
set /A paramCount=paramCount+1
)
I also forgot to mention that the program works fine when I run the Java from Eclipse; it calls the batch files correctly and all works as expected. I don't get the error until I export the project to a runnable JAR and try running that.
EDIT 2:
After going through my batch file code again (I wrote it a while ago), I found only one line that looks like it might cause this problem. The odd thing is that I used an almost identical code example I found somewhere else to model it, and it worked for a long time without ever giving the error. It's a loop, designed to loop through the elements of the list "array" created in the first loop:
for /F "tokens=2 delims==" %%d in ('set list[') do (
set /A paramCount+=1
set _dir=%%d
set _dir=!_dir:"=!
if NOT "%%d"=="nul" set "dirs[!paramCount!]=!_dir!"
)
As you can see, the first line has a segment that says set list[, which looks odd to me. However, as I mentioned, it worked fine for quite a while.
The code you posted cannot give that error message. There must be some other code in your script that causes that error.
Only a SET statement without an = could give that error. After parsing and expansion, the offending statement must look like one of the following:
set list[
set "list[
set "list["
Actually, you could get that error in the presence of an = if there are quotes that are misplaced. For example, the following will give that error because all text after the last " is ignored:
set "list["1]=value
The 1]=value appears after the last " and is ignored, leaving set "list[".
You might consider enabling ECHO so that you can pinpoint exactly where the error message is occurring. Then you need to figure out what conditions could lead to the error at that point.
Update in response to "Edit 2:" in question
That IN() clause in the newly posted code is almost assuredly the point where the error message is generated. It indicates that the list "array" is not defined when the FOR /F loop is executed. The question is, why not? Things to look for:
Is something preventing the earlier FOR loop that defines the list "array" from running?
Are you sure the parameters are getting passed properly to the script? If there are no parameters, then there will not be an array.
Is something undefining the array before the 2nd FOR loop has a chance to execute?
I suggest you put in some diagnostic ECHO statements to help debug. For example, ECHO BEFORE 1ST LOOP immediately before the loop that defines the array to make sure the loop is being reached. Or ECHO ARGS = %* at the beginning of the script to make sure the parameters are getting passed properly. Happy sleuthing :-)
I tried the code bellow and it worked for me when calling from command line.
#echo off
setlocal enabledelayedexpansion
set paramCount=0
for %%x in (%*) do (
set /A paramCount=!paramCount!+1
set list[!paramCount!]=%%x
)
echo !list[1]!
echo !list[2]!
echo !list[3]!
I mentioned it in the comments but I figured I'd post an answer, for anyone else who's wondering:
As previously mentioned, the program was running fine in Eclipse, the batch files were being called and ran as expected. However, prior to making some changes to the batch files, I had created .exe's from them, and apparently was running the .exe's instad of the .bat's. It was a very stupid mistake on my part, and the problem was caused by some errors in the previous version of the batch file. If I remember correctly, that error was because the "array element" was empty. So I ended up doing a check to make sure it wasn't empty before operating on it. The following is the code i am currently using, and it works as expected:
#echo off
setlocal ENABLEDELAYEDEXPANSION
set /A paramCount=-3
for %%x in (%*) do (
set list[!paramCount!]=%%x
set /A paramCount=paramCount+1
)
set argA=%list[-3]%
set argB=%list[-2]%
set argC=%list[-1]%
for /F "tokens=2 delims==" %%a in ('set list[-') do SET "%%a="
set list[-3]=""
set list[-2]=""
set list[-1]=""
set paramCount=0
for /F "tokens=2 delims==" %%d in ('set list[') do (
if not "%%d"=="" (
set _dir=%%d
set _dir=!_dir:"=!
if NOT "%%d"=="nul" set "dirs[!paramCount!]=!_dir!"
)
set /A paramCount+=1 )
Thanks for all the answers, folks!
Related
a specific directory receives some different files including some .cmd files.
Here is and example of one of these:
X_COMMAND=DELETE_DOCUMENT
X_DOCIDENTIFICATION=FREE
DTY=MSDS
X_DELIMITER=;
X_FollowingFields=STA;DTY;PRN;SID;CTY;LAN;VKG
V;MSDS;340000021613012300;800000000160;ES;E;ES00
I want to work with the last 2 lines of Code to extract Data:
String xyz = (the command to get 340000021613012300);
The Question is: How do I get this Data?
I have tried to look this up, but did not find anything regarding this issue. If you can help me with this or redirect me to the information I look for I would appreciate that.
Thank you for your time helping me here.
Here is one way to do it. If you are on a supported Windows system, PowerShell will be available.
FOR /F %%A IN ('powershell -NoLogo -NoProfile -Command ^
"(Get-Content -Path "C:\src\t\Get-LastLineData.txt" |" ^
"Select-Object -Last 1).Split(';')[2]"') DO (
SET "xyz=%%~A"
)
ECHO %xyz%
If your script could be written in PowerShell, it would just be:
$xyz = (Get-Content -Path "C:\src\t\Get-LastLineData.txt" |
Select-Object -Last 1).Split(';')[2]
Using just cmd:
for /f "tokens=3 delims=;" %%a in (file.ext) do set "xyz=%%a"
echo %xyz%
(assuming you want the third token of the last line)
I have a batch file roughly with the following code:
#echo off
(
set /p x=
set /p y=
) < settings.cdb
IF DEFINED x (
IF DEFINED y (
ECHO true
GoTo :EOF
)
)
ECHO false
GoTo :EOF
In Java, I have the following code to call the batch file via command line:
ProcessBuilder probuilder = new ProcessBuilder(command);
Process pr = probuilder.start();
BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line;
while ((line = input.readLine()) != null)
{
lines.add(line);
}
X and Y are some input parameters from a configuration file, which may, or may not, contain any data.
When x or y are not defined everything works as suppose, outputs false.
The problem comes when the variables are both defined.
When the batch file gets called via command line I get the resulting output: true. Which is the intend output.
When I call the same batch file via Java Process I get the following output:false. Which is not what I want.
Removing the #echo off I get the following output from running the batch file from command line:
IF DEFINED x (IF DEFINED y (
ECHO true
GoTo :EOF
) )
true
But when I run it from Java Process:
IF DEFINED x (IF DEFINED y (
ECHO true
GoTo :EOF
) )
ECHO false
false
GoTo :EOF
It is not even outputting the echo true.
I've tried with EXIT /b 0 instead of GoTo :EOF but with the same result.
So what am I missing here? Why the program, when called from Java, keeps going even though it has a GoTo :EOF?
Why the different outputs? Is it a Java thing? Is it a batch thing?
UPDATE:
After all the file from where variable were being loaded is relative to the command line location instead of the bat location.
Well, you said it: "It is not even outputting the echo true". When you add debug lines, it.. helps to think for a second about what it means. 'x' is not defined, or 'y' is not defined (or most likely both are not defined).
You can manage the environment of the spawned process, use ProcessBuilder, and before launching (with e.g. start()), first set up the environment; for example with pb.environment.put("x", "hello");.
Why are you running batch scripts from java, though? They were bad technology back in the 80s, and there are a ton of alternatives available at this point. If you explain what you're trying to accomplish by farming work out to a batch file, perhaps an enterprising SO reader can make some useful suggestions.
When I tried to run Ansible with Runtime.getRuntime().exec with Java
Here is what I did:
String[] cmd = {"ansible-playbook", "/path/to/playbook", "--extra-vars", "'{\"filePath\":\"/path/to/file\"}'"};
Process process = Runtime.getRuntime().exec(cmd, null);
I got error message like this:
FAILED! => {"failed": true, "msg": "'filePath' is undefined"}
However when I executed the same command with terminal:
ansible-playbook /path/to/playbook --extra-vars '{"filePath":"/path/to/file"}'
Everything was fine...
I think there must be some differences between the command I ran in terminal and Java, maybe apostrophe or quotation mark ?
I'm wondering is there any way to get the real executed command of Runtime.getRuntime().exec? Just like I can get command line history of some user by history...
You are adding additional quotes in your third parameter:
"'{\"filePath\":\"/path/to/file\"}'"
If you do this, you're not executing the same command in your shell as you have above. You're actually executing (in bash):
ansible-playbook /path/to/playbook --extra-vars ''\''{"filePath":"/path/to/file"}'\'''
You don't need the single quotes around the value here: because you're passing these values directly, you don't have to worry about the quoting that you'd have to do in a shell. You can simply use:
"{\"filePath\":\"/path/to/file\"}"
First time poster here! I usually lurk for answers but seeing as I've been getting a headache on this and I really want this done for my boss I wanted to directly ask and see if anyone can spot what is wrong with my script.
#echo off
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value')do set "dt=%%a"
set "YY=%dt:~2,2%" & set "YYYY=%dt:~0,4%" & set "MM=%dt:~4,2%" & set "DD=%dt:~6,2%"
set "HH=%dt:~8,2%" & set "Min=%dt:~10,2%" & set "Sec=%dt:~12,2%"
set "datestamp=%YYYY%%MM%%DD%" & set "timestamp=%HH%%Min%%Sec%"
set "fullstamp=%YYYY%-%MM%-%DD%_%HH%-%Min%-%Sec%"
set "new_name=PayCase_%fullstamp%"
echo datestamp: "%datestamp%"
echo timestamp: "%timestamp%"
echo fullstamp: "%fullstamp%"
move /-y "E:\RFT workspace folder\PayCase_Project_Playground_logs\PayCase_ScriptLog" "%~dp0\Log Archive\%new_name%"
xcopy /e "%~dp0\Log Archive\%new_name%" "%~dp0\Log Archive\sendFolder"
pause
EXIT
This first part of the script just gets today's date and time and sets it to a var called 'new_name' (it's not my code, got it from somewhere, I forget where). The latter part, moves the contents of the folder from one place to another, then it is suppose to copy those contents to another place in the drive.
Can someone help me figure out why my code is not copying the contents to my sendFolder?
The only thing I see is that you are not using all the switches. Try it with switches /s. Second and most importantly you are using the %~dp0 WRONG!
Type this in a txt file and save it as a batch file
Echo %~dp0
Pause
Run it, you will already find a \ at the last so for example you would have a path like this C:\Wherever\bat\is\ at the last there is already an \.
You have typed this "%~dp0\Log Archive\%new_name%" which would result in "C:\Wherever\bat\is\\Log Archive\%new_name%".
See that? A slight mistake can get the whole thing wrong. So try adding the /s switch and editing your code like this
xcopy /s /e "%~dp0Log Archive\%new_name%" "%~dp0Log Archive\sendFolder"
Please also follow #JosefZ Comment
Regards,
I am trying to start a Java-process using Go but am unable to get Java to recognise the classpath. The code looks somewhat like:
args := []string{
"-Xmx64m",
"-Dmy.property=value,
"-cp",
"lib/jar1.jar:lib/jar2.jar",
"com.things.MyClass",
}
c := exec.Command(javaBinary, args...)
Unfortunately when executing this I get the dreaded Error: Could not find or load main class from the JVM. However if I take the output from c.Args and run it directly in a terminal it seems to work just fine, which to me indicates that I am somehow launching the process incorrectly.
Is there a better way of doing this?
Disregard this question please, the error was an extra space in the args array:
args := []string{
"-Xmx64m",
"-Dmy.property=value ", //<--trailing space
...
}
The extra space stops further parsing from continuing leading to a missing classpath.