Tracing Batch Variable - batch-file

I have this batch which executes on the server computer. There is a scheduled job which runs the batch. The Batch detects a particular file and then it executes an sqlcmd like below:
if not exist %TRIG_FILE% goto No_Triggers
sqlcmd
-S %WSL_SERVER%
-d %WSL_DATABASE%
-E
-Q "DECLARE #RES integer;DECLARE #RET varchar(1);DECLARE #MSG varchar(65);EXEC Ws_Job_Release 1,'Release Job Unlock Batch','All',0,0,'Unlock_Batch',#RET OUTPUT,#MSG OUTPUT,#RES OUTPUT"
My question is - how did the batch know what the %WSL_SERVER% variable is, because when I look at the script, there is nowhere in there which sets the %WSL_SERVER% variable.
This is the first time I'm reading a .bat script, I know a fair bit of programming, but I can't see how that variable was passed into this script so that it knows which server. There's no other batch calling this, it's from the batch run by the scheduler.
thanks
gemmo

Most likely the WSL_SERVER and WSL_DATABASE are global environment variables initialised every time with your Windows session. That means they exist (are defined) in every CMD session and thus in every batch script. You can open a new Command Prompt window and issue this command
SET WSL
which will (try to) display all environment variables, whether global or local, whose names start with WSL. My guess is the output will show you at least the two WSL variables used in your script.
There is a number of global variables pre-defined and maintained by the OS. Yours, however, are probably user-defined (just my guess based on the fact that my system does not have them). User-defined variables can be created by third-party software or your own (maybe someone else's) batch scripts, as well as with a standalone invocation of the SETX command:
SETX VarName "Value"
You can use that command to change the value of any of your variables globally. Note that you can also change that value temporarily only, for the duration of the script, using the SET command as usual, if global change is undesirable:
SET "VarName=Value"

Related

How to fetch the environment variables that are set for the current instance of cmd.exe?

I have a cmd batch script that sets some variables. I tried the command SET, but it lists all the environment variables, including the system default ones (or Global ones). I am interested in knowing exactly the ones which are being set inside that script. Is there any way to do that from the command line?
Also, let's say I exported all the environment variables in a text file. Can I set them all at once in a new cmd.exe instance by providing the file path? Or, looping through each one of them is the only option?
Edit: I can't modify the original batch script and don't have any control over it's future changes.

Permanent variables for batch files

My program is a GUI based install and run tool for a certain program, when I say GUI, I mean batch files. When it installs a program, it needs to always know where it is installed, currently, it just records it into a variable, but that only works if they don't shut the program and return at a later date, so I wanted to know a way of storing a permanent variable.
I was thinking maybe something like this:
set instloc='C:\Users\JoeBloggs\Documents\Environment\My Programs\This program.exe'
echo %instloc% > instloc.txt
attrib +h instloc.txt
But I was wondering if there was a dedicated command for it
Set modifies the current shell's environment values, and the change is temporary but available immediately. The change will not affect other shells that are running, and as soon as you close the shell, the new value is lost.
setx modifies the value permanently, which will affect in all future shells, but does not modify the environment of the shells already running. You have to exit the shell and reopen it before the change will be available, but the value will remain modified until you change it again.
In your case, instead of using set use setx:
setx instloc "C:\Users\JoeBloggs\Documents\Environment\My Programs\This program.exe"

Use environment variable set by a batch script in the next batch script run

Actually i want to run 2 bat scripts , first script will set a system variable set NEWPATH="E:/Some" and second script will show the path of that variable: echo %NEWPATH%. this is not working with the same server at first time , when i restart server that will show the path otherwise it'll show nothing. so can anyone help me on that?
I don't fully grasp your problem, but here's a couple of observations.
Some theory
Environment vaiables set in a batch file (which is being executed by a shell process, cmd.exe)—or any other kind of process—can only be set for that very process.
That is, each process has a special block with environment variables made available to it by the OS when that process is created.
This also means that when the process which set an environment variable is finished, it's environment block is gone.
An environment variable can be inherited by a process which was started by the process which has set that environment variable.
What happens in your case
What this means is that if you run two batch scripts in a sequence, this means
The first cmd.exe process is strated, the batch script it executed
set an environment variable; then the process is gone, and its environment block is gone, too.
Then another cmd.exe is started, it inherits the environment block of your host process (written Go), but as you can see, whatever is set by a first batch script is not available.
What you can do about it
There are two possible ways to solve the problem:
Make the first batch script call the second one by itself.
In this case the second cmd.exe will inherit the environment variables
set by the first script and will hence "see" them.
Note that the Windows batch command language supports the calls
command to call out to other batch scripts by their pathnames.
Make the first script communicate the value of that variable to your host process and then arrange in the host process for the second cmd.exe to have the indicated variable with the indicated value in its environment.
Say, the first script could just do something like
echo VARNAME=value
to have
VARNAME=value
printed to its stdout.
Your Go process could parse that output, tear it apart on the =
character, sanitize to not affect "interesting" variables like PATH,
USERPROFILE etc, and then the host process could do
env := os.Environ()
env = env.append("VARNAME=value") // real value here
...
cmd := exec.Command(`cmd.exe`, `/c`, secondScriptFilePath)
cmd.Env = env
...
cmd.Run() // or whatever
The second case can be done a bit differently: the host process
can call os.Setenv("VARNAME=value") to make this variable appear in its
own environment block; it then will be inherited automatically by whatever processes it starts after that.
Update to address the OP's comment
…script files will be in client side so i can't add a line
echo VARNAME=value .
so is there any other possible way to do this?
There's another approach which might work in your case.
The idea is that cmd.exe is just a shell: when it's started non-interactively (that's what is done by exec.Command("cmd.exe"))
it reads commands from its standard input stream and executes them one by one—until the stream is closed (by the sender).
Hence you can do the following:
Start cmd.exe while connecting an instance of io.Pipe to its Stdin.
Open the first script yourself and shovel it at the running cmd.exe via the pipe set up on the first step.
Don't forget to Flush() the pipe.
You can use the io.Copy() function which sends all the data from an opened io.Reader to some io.Writer.
Leave the shell instance running.
When it's time, read the second script and shovel it at the same shell.
Since the shell is the same, the second script would run as if it were physically appended to the first one, and will see all the variables set by the first script.

Setting "echo on" globally for batch scripts

I have experienced (random) weird corruption of environment variables from consecutive calls of multiple (3d party) batch scripts. These individual scripts call #echo off.
Is it possible to force echo on by environment variable/other means or I need to go to the every script and comment/remove the line to see what has been actually executed?
I'm quite sure that this is not possible. You can't force your system to simply ignore a command like ECHO OFF. The only way to I can think of as a workaround is to write a script which replaces all ECHO OFF commands in you bat files before execution and restoring them afterwards.
Take a look at this: https://superuser.com/questions/351661/how-do-i-force-echo-on-for-a-batch-file-without-editing-the-file

I need to write a batch file to set the system environmental variables ,

I need to write a batch file to set the system environmental variables as shown below
WRD_WF_ROOT=e:\wrd_ntl_v23
WRD_Wld_ROOT=e:\wrd_ntl_v23
and I need to run the script for 250 users .
I think you are looking for setx, it is like a normal set but it survives after your computer restarts.
I'm assuming you mean non-volatile system wide variables, if that is the case, you can call reg.exe and add your entries to HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment (reg.exe is available by default on WinXP+)
To execute things on remote machines, psexec is your friend.

Resources