escaping the special characters without knowing the position batch - batch-file

I have a requirement to execute a batch file with the arguments. the problem occuring here is I am not sure what special characters and at what place it can occur. I have gone through possibly all the answers here but still unable to fix the issue. Any help is appreciated.
Command that i am trying to run within the batch file
CALL E:\myscript.bat -run e:\param -password %PASSWORD%
where PASSWORD is the variable storing the password and it can be having any special characters at any position.

Maybe I understood your question, it would be:
You want to identify, without having to have specific argument
positions, what each argument represents.
Or:
You want to find a solution to handle the arguments so that they do
not result in errors because they contain special characters
Anyway, I will answer both.
You have some alternatives for doing so, some may be more ideal than others depending on how you are handling your code and its purpose.
In case you identify the arguments and what they represent, you can:
set args=%*
Some things may help you make your code stable while using an wildcard without its effect. Like:
set "args=%args:&=^&"
But the most important thing is to keep the code without quotes. In fact, the use of CALL is not necessary if you are not doing it within a script.
set "args=%args:"=%
The next thing to do is to identify the parameters. We can do this both in a crude way and in a simpler way, which would be defining each argument with its own variable, such as: arg1=%1, arg2=%2...
You can now pass all parameters into a treatment and reconstruction session.
Assuming you want to identify -password:
---during a FOR loop to catch and make the same processes at every arg---
(which I can only guess because you didn’t show the code or anything like that)
if "!arg[%%x]:~0,1!" equ "-" (
if "!arg[%%x]:-=!" equ "password" set /a x=%%x+1&set "password=!arg[%x%]!"
if "!arg[%%x]:-=!" equ "run" set /a x=%%x+1&set "run=!arg[%x%]!"
...
)
Obviously there are some things that can improve in this code, but you have shown almost nothing for us to use as a reference to answer, so that's all I can do.
Hope this helps,
K.

Related

Expanding variables in IF statements in batch

So I need to see if a string contains something. I was thinking, you know how you can do set VAR=%VAR:-=_% to target certain things inside the variable and change them with the set command. Well, is there a way I can do this with "IF" statements?.
Example of what it might look like:
if %VAR%==%VAR:word% echo yes
This command doesn't actually work but if it did, it would look to see if %VAR% contains "word" anywhere in it.
You're very close, but you've only got half of a valid string substitution command, which isn't causing a syntax error, but it is causing a flow in the logic: right now you're comparing %VAR% to a variable that the interpreter can't access.
If you use string substitution to remove the word you're looking for and then compare that to the original variable, you can use an if not statement to determine if the variable was updated by the substitution.
if not "%var%"=="%var:word=%" echo yes

Dynamic variable name in cmd.exe w/ command extensions

I see this is a common theme, but I believe I have a unique problem.
I want to use this technique of variable expansion, where you can use the ":" to substitute strings in expanded result (the "&" part being a trick to force command execution)
echo %PATH:;=&echo.%
, but like this:
set VAR=PATH
set DELIM=;
set SUBST=echo.
echo %VAR:%DELIM%=&%SUBST%%
Well, I hope you get the point. The above is not valid code.
Anyone has a clue?
The example in the question should be considered generic, and not to be taken literally. The question is can it be done and exactly how?

Calling batch file with parameter containing space

I have a very simple problem:
call myBatch.bat "K:\dir name with spaces\eatThis.xml"
Which will not work, it will stop with
K:\dir does not exist
Could you please point me to the SO question addressing such an issue? I've already dug myself through quite a lot of SO questions regarding batch files and whitespaces in parameters but I guess the solution to my problem must have been ignored accidentally.
--
OK, after some debugging it turned out that it was not the batch file that was faulty but the Java application that invokes String.split(" "); to separate multiple arguments from each other. So when one argument contains a space, in its path, the application logic falls apart. As the original question no more describes what the real problem is, shall I rewrite it completely or write a new one? Anyway, my bad, feel free to downvote is.
I created the following mybatch.bat and started it with call myBatch.bat "K:\dir name with spaces\eatThis.xml" Output is:
"K:\dir name with spaces\eatThis.xml"
Mybatch.bat:
echo off&setlocal
echo "%~1"

To "Call" or "Not to Call" a batch file?

If from inside a bat file you called another batch file but still had a few remaining operations to complete, how can you make sure that the call to first bat file will after completion or error, will return to the file that called it in the first instance?
Example:
CD:\MyFolder\MyFiles
Mybatfile.bat
Copy afile toHere
or
CD:\MyFolder\MyFiles
CALL Mybatfile.bat
COPY afile toHere
What is the difference between using CALL or START or none of them at all? Would this have any impact on whether it would return for the results of the copy command or not?
As others have said, CALL is the normal way to call another bat file within a .bat and return to the caller.
However, all batch file processing will cease (control will not return to the caller) if the CALLed batch file has a fatal syntax error, or if the CALLed script terminates with EXIT without the /B option.
You can guarantee control will return to the caller (as long as the console window remains open of course) if you execute the 2nd script via the CMD command.
cmd /c "calledFile.bat"
But this has a limitation that the environment variables set by the called batch will not be preserved upon return.
I'm not aware of a good solution to guarantee return in all cases and preserve environment changes.
If you really need to preserve variables while using CMD, then you can have the "called" script write the variable changes to a temp file, and then have the caller read the temp file and re-establish the variables.
call is necessary for .bat or .cmd files, else the control will not return to the caller.
For exe files it isn't required.
Start isn't the same as call, it creates a new cmd.exe instance, so it can run a called batch file asynchronosly
The `CALL' statement was introduced in MS-DOS 3.3
It is used to call other batch files within a batch file, without aborting the execution of the calling batch file, and using the same environment for both batch files.
So in your case the solution is to use CALL
Okay, I actually didn't even really think about the fact that if you call a batch (regardless of the 'type', i.e. '.bat', or '.cmd') that it won't return if you don't use call.
I've been using call myself though for a different reason that I am actually pretty surprised that no one else has brought up. Maybe I missed it. MAYBE I'M THE ONLY ONE IN THE WORLD WHO KNOWS!! :O
Probably not, but I'm going to drop this knowledge off here because it's super useful.
If you use call you can use binary logic operators to decide how to proceed based on the ERRORLEVEL result. In fact, I always was flabbergasted on how && and || existed in DOS and COULDN'T be used this way. Well, that's why.
The easiest way to test this is to create a return.cmd with notepad, or from the command prompt like so:
c:\> type con >return.cmd
You will now notice the cursor goes down to the next line and hangs. Enter:
#exit /B %1
And then hit ENTER, and then CTRL-Z and that file will be created. Good! You may now feel free to try the following two examples:
call return.cmd 0 && echo Huzzah! A Complete Success! (Or cover up...)
call return.cmd 123 || echo Oops! Something happened. You can check ERRORLEVEL if you want the tinest amount of additional information possible.
So what? Well, run them again with the 0 and the 123 swapped and you should see that the messages DON'T print.
Maybe this multi-line example will make more sense. I use this all the time:
call return.cmd 0 && #(
echo Batch says it completed successfully^^!
) || #(
echo Batch completed, but returned a 'falsey' value of sort.
call echo The specific value returned was: %ERRORLEVEL%
)
(Note the 'call' in the || section before the second 'echo'. I believe this is how people got around not having delayed expansion back in the day. If you DO have delayed expansion enabled (via. setlocal EnableDelayedExpansion inside a batch OR launch a command prompt with cmd /v:on then you can just do !ERRORLEVEL!.)
... This is where I have to apologize and say if you have if ERRORLEVEL trauma in your past you should stop reading. I get it. Trust me. I thought about paying someone on fiverr to remotely type this for me, but for completeness sake I'm just going to take one for the team and mention that you can also do the following to check errorlevel:
if ERRORLEVEL 123 #echo QUICK! MOTHERS, COVER YOUR CHILDREN'S EYES! FINGERS ARE BEING UNDONE! :'(
If you've never typed that before then GOOD! You will live longer without having to read up why exactly you aren't getting the results you expect. Cruel is the word you're looking for, not 'quirky'.
The important part that I really want to get across however is that if you try this and DON'T use 'call' it will ALWAYS execute the 'true' branch. Try it for yourself!
If I'm missing something, or you know a better way to do this, please let me know. I love learning stuff like this!
Additional information I mentioned:
I have known for quite some time that you can put redirects BEFORE commands like so:
>nul echo. This won't be displayed!
But I accidentally discovered the other day by being a dumdum that you can apparently also do:
echo A B>file.txt C
And was REALLY surprised to find a file.txt which consisted of "A B C". It appears yo can place them ANYWHERE, even inside the command. I've never seen anyone do this, nor mention it, but I HAVE seen people mention that you can prefix a line with them.
Maybe it's a bug exclusive to Windows 10 or something. If you have another version and wanna try it out and let me know I'd be interested in what you find out.
Stay nerdy!

Obfuscation and/or antivirus hiding of a batch file using SET. Would it work?

Hullo, I was just wondering whether a plain SET parameter could be used for obfuscations or any other protection from antivirus in Windows batch files.
I ask because I recently obtained the two "famous" batch virus scripts "PiFv," and "meLT." For study of course. They kept getting detected by antivirus, so I would disable it, study for a while and it would be deleted again. Lucky I have internet ;) Anyway, I tried to think of a way to hide the virus'.
I thought maybe because they are analyzed by string, merely a text change would help. So I used inconspicuous words like so
SET hello="# Echo off"
%hello%
And so on. Unfortunately, Norton was clever enough to suss it (surprisingly) though it's status was lowered from "Infectious" to "Heuristic." I figured if it had gone from yes to maybe this could work.
Next I went on single letter changes making words, example, if I was to print "infect;"
set z=i
set h=n
set j=f
set x=e
set d=c
set q=t &echo %z%%h%%j%%x%%d%%q%
That has half worked. Although a lengthy process I think if a set alphabet was established then changed it might. Anyway, the half working. It is classed heuristic when off a USB, but not classed if off a floppy. Why? Also, do you think this is a good idea?
Half way through reading your question I thought the same as your second idea, splitting the words.
I can't test as different AV's will detect different things, but maybe try splitting them into half's instead of single letters, so it doesn't take as long to do.
set z=inf
set h=ect
echo %z%%h%
Another option would be to read in the complete commands from a text file
set /p z= <command.txt
echo %z%

Resources