Batch Program Produces Strange Unexpected Output - variables

Before I remembered how to accomplish what I was doing, I tried a couple different things, kind of just hacking at it.
What I was trying to accomplish was to set the following string as a variable and then echo it out in a batch script:
<?php require('__php__.php'); ?>
I eventually worked it out with help from SO, but before I got there, I tried this (for some reason):
set (phpStr=<? php require('__php__.php'); ?>)
Which I realize doesn't make any sense. However, how the cmd shell interpreted what I wanted to do was as follows:
set (phpStr= php require('__php__.php'); ? 0<? 1>)
In other words, when I typed the code in the second code block above, and turned on echo in the script, what showed up in the cmd shell was the command in the third code block. Then there was a syntax error, and the script exited.
Can anyone explain what happened? (Not why it didn't work. That is obvious to me, but rather, how it arrived at the interpretation it did. It's a pretty awesome restructuring of the original command. I just can't figure out how it got there.)

You need to escape redirection and other poison characters with ^ or the redirection will be active and try to create files etc. % is a special case.
You can also use something like this:
#echo off
for /f "delims=" %%a in ("<?php require('__php__.php'); ?>") do echo %%a

Related

Best way to process set variables in batch files

This question is probably unnecessary as I probably have been searching for the wrong criteria. It's pretty easy I think but I just can't find the answer. I use batch files to automate installs with my work, setting folder permissions, copying files here, and there, silently running programs, removing old ones etc. The batch files contain lots of repetition and I want to tidy them up greatly for easier management. I have decided to set the repeated commands and copy folder locations as variables then use them instead. This is all fine but I'm adding the variables as a LIST which looks rubbish to me, I'm sure I can load them together in a sentence rather than a new line for each. Here's what I mean...
set dir1=md c:\newfolder
set killtask=taskkill /im someprog.exe /f >nul 2>&1
set config=echo F| XCOPY %~dp0configfile3.cfg /y C:\newfolder
And on and on...
So at the minute my batch now looks like this
JOB1
%dir1%
%killtask%
%config%
What I want to be able to do is have it like this (to reduce length if batch file etc.)
JOB1
%dir1% %killtask% %config%
(summary of my comments to the question):
Check your variables! Some chars like pipe (|) or redirection (>) change how the line is interpreted. Use this syntax to correct it:
set "killtask=taskkill /im someprog.exe /f >nul 2>&1"
(note the quotes and their position)
you can call several commands with &:
echo hello&echo world.
With your complex variables this would probably fail/work in an unexpected way. Try
(%dir1%)&(%killtask%)&(%config%)
so that the redirections and pipes stay at their intended commands.

How to .. batch file which executes information in a text file

Sorry not much experience with batch files hence help needed please! ;-)
I'm working in a DOS box on a Windows 7 64 bit system.
I want to run an application as a batch file, but reading the information it needs from a text file which can be updated/amended regularly.
The syntax of the basic application is:
appname "variable" (the variable MUST be enclosed in quotes)
Successive variables can be concatenated to the following single line format:
appname "var1" "var2" "var3" "var4" ... etc
So I've created a batch file containing the above. However, this is unweildy when it comes to updating. Sometimes I omit the delimiting quotes which creates problems in the execution of the batch file.
It seems to me that from an updating/amending point it would be easier to set up a text file, say text.txt which would contain the following information:
"var1"
"var2"
"var3"
"var4"
etc. on successive lines.
This would make it easier for me to update and also to ensure I don't omit the delimiting quotes.
The batch file would get the application to "read" the text file, execute the first variable, then the second etc all the way through to the end. But I'm not sure if this is possible and if so, how to get the batch file to read successive lines in the text file and use those variables.
As I said earlier, I've not much experience with batch files and don't have a clue how to do this! :-(
Help please, thanks
Alan
Like this :
#echo off
set $textFile="test.txt"
for /f "delims=" %%a in ('type %$textFile%') do appname.exe %%a
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "batchline=appname"
FOR /f "delims=" %%a IN (q25193799.txt) DO SET "batchline=!batchline! "%%~a""
ECHO(%batchline%
GOTO :EOF
I used a file named q25193799.txt containing your data for my testing.
The application line is merely echoed for verification. Remove the ECHO( after verification to execute your application.
The data in the file need not have "enclosing quotes".
Thanks to both responses, both different but good in their own way. I use a few different instances and I've decided to use the first response for the longer lists and the second one for shorter lists (that way I can check see if something is going wrong, because I might have missed the second delimiting quote in the text file.
Superb, thanks to you both.

How would I call a dynamic variable name?

Okay, so I'm trying to make a program that "understands" user input and does what they tell it to do. People usually just use specific commands such as "open this file" and it only works if the user types EXACTLY that. I'm trying to give my users a little bit of leeway, so that they can type something like what they want to happen, and the computer will get the general idea. With that block of rambling aside, I've run into a problem.
set word%wordNum%=%word%
:fileExtension
set extChk= %letterNum% - 2 REM Includes the period of the extension
call set extension=%%_albaiRec:~%extChk%,4%%
::extChk is checking for a period so the program will recognize a file extension
set file=
That last line is where I get stuck...
I'm trying to use that last recorded word variable.
set var=7
set word7=Wanted text
echo %word%var%%
Sorta like that?
Add setLocal enableDelayedExpansion to the start of your script.
Then replace echo %word%var%% with echo !word%var%!.
For more information - http://ss64.com/nt/delayedexpansion.html

Zsh trouble when using echo with color/formatting characters

I'm just switch to zsh and now adapting the alias in which was printing some text (in color) along with a command.
I have been trying to use the $fg array var, but there is a side effect, all the command is printed before being executed.
The same occur if i'm just testing a echo with a color code in the terminal:
echo $fg_bold[blue] "test"
]2;echo "test" test #the test is in the right color
Why the command print itself before to do what it's supposed to do ? (I precise this doesn't happen when just printing whithout any wariable command)
Have I to set a specific option to zsh, use echo with a special parameter to get ride of that?
Execute the command first (keep its output somewhere), and then issue echo. The easiest way I can think of doing that would be:
echo $fg[red] `ls`
Edit: Ok, so your trouble is some trash before the actual output of echo. You have some funny configuration that is causing you trouble.
What to do (other than inspecting your configuration):
start a shell with zsh -f (it will skip any configuration), and then re-try the echo command: autoload colors; colors; echo $fg_bold[red] foo (this should show you that the problem is in your configuration).
Most likely your configuration defines a precmd function that gets executed before every command (which is failing in some way). Try which precmd. If that is not defined, try echo $precmd_functions (precmd_functions is an array of functions that get executed before every command). Knowing which is the code being executed would help you search for it in your configuration (which I assume you just took from someone else).
If I had to guess, I'd say you are using oh-my-zsh without knowing exactly what you turned on (which is an endless source of troubles like this).
I don't replicate your issue, which I think indicates that it's either an option (that I've set), or it's a zsh version issue:
$ echo $fg_bold[red] test
test
Because I can't replicate it, I'm sure there's an option to stop it happening for you. I do not know what that option is (I'm using heavily modified oh-my-zsh, and still haven't finished learning what all the zsh options do or are).
My suggestions:
You could try using print:
$ print $fg_bold[red] test
test
The print builtin has many more options than echo (see man zshbuiltins).
You should also:
Check what version zsh you're using.
Check what options (setopt) are enabled.
Check your ~/.zshrc (and other loaded files) to see what, if any, options and functions are being run.
This question may suggest checking what TERM you're using, but reading your question it sounds like you're only seeing this behaviour (echoing of the command after entry) when you're using aliases...?

Variable assignment in batch

This question seems to be (very) stupid be I can't deal with it :(
When I tried this batch code:
if "%1" == "-i" (
set is = %2
echo. %is%
shift
)
called with 2 (or more) arguments, it does NOT work. It actually prints a blank. The "shift" command is not done either. When I watch the executed code (without the #echo off at the beginning), I can see that the "set" command is completed.
What's wrong with it?
Example of calling:
c:\script.bat -i test -d bla
You have two issues. By default group of statements in parens will have variable expansion done all at once, that is before your set command. Also the semantics for set is wrong, you don't want spaces around the =.
Add this to the top of your file:
setlocal ENABLEDELAYEDEXPANSION
and remove the spaces around = in set:
set is=%2
Finally used delayed expansion:
echo. !is!
A possible third issue is you may need two SHIFTs, one for -i, one for it's is argument.
Update
Thanks to #dbenham for pointing out that it wasn't a syntax error with set, it's just surprising behavior that deserves a little explanation. If you execute these commands:
set a=one
echo "%a%"
The result is:
"one"
That makes sense, but try:
set b = two
echo "%b%"
And you get:
"%b%"
What? This is what you would expect when environment var b is unset. But we just set it. Or did we:
echo "%b %"
Displays:
" two"
For the Windows set command, unlike any other language or environment I'm aware of, the spaces are significant. The spaces before the = become part of the environment var name, spaces after become part of the value. This uncommon behavior is a common source of errors when writing Windows batch programs.