What is the difference between !call and call in windows batch - windows

There are 2 files: file1.bat, file2.cmd
file1.bat invokes file2.cmd through command:
db2cmd -i -c -w db2 !call file2 parm1 parm2
This command opens a DB2 command window at the same window and invokes file2.cmd
However, what I can't understand is the function of '!' in front of 'call'.
file2.cmd has below features:
1. DB connection: db2 connect to dbname user username using psw
2. File open: for /F "delims=;" %%i in (input.txt) do (do something)
If passing the incorrect parameters,
---------With 'call' in the file1 command, error shows:
SQL1024N A database connection does not exist. SQLSTATE=08003
---------With '!call' in the file1 command, error shows:
SQL1001N "xxx" is not a valid database name. SQLSTATE=2E000
The system cannot find the file \input.txt.
DB20000I The TERMINATE command completed successfully
So, it looks like 'call' invokes another file and break with high level error message once one of the command fail;
While '!call' invokes another file and continue to run all the commands insides even though there are error, then displays all the error messages of all the failure.
Can someone advise the difference between 'call' and '!call'?

Ok, so simply put, there is no function !call in batch/cmdline. So db2cmd.exe being a commandline processor itself, requires you to use system commands with a preceding !
So though you have a batch file that runs the command with parameters, effectively this is what happens. You are starting db2cmd from this cmd, it then requires you to call another batchfile, but seeing as we are not within the shell of cmd anymore, but rather inside of db2cmd you're then required to tell db2cmd that it is a system command you're executing by doing !call
You can test it by doing on its own db2cmd where you will get to a db2=> prompt and then try and use call vs !call from there.
As for your error message:
SQL1001N "xxx" is not a valid database name. SQLSTATE=2E000
The system cannot find the file \input.txt.
DB20000I The TERMINATE command completed successfully
Try and add a path to the input.txt file
for /F "delims=;" %%i in (C:\somepath\input.txt) do (
something
)
or place input.txt in your working dir.

There is an easier way to handle running Db2 CLP commands inside a Windows batch file.
Db2 on Windows requires that Db2 CLP commands run inside a db2cmd.exe window.
(otherwise a db2 command in a normal cmd.exe window may fail with an error).
The db2cmd.exe is shipped with the Db2 Client for windows.
The solution is to arrange that the script auto-detects whether it is running
inside db2cmd.exe , and if not then run itself under db2cmd.
With this approach the calling script (if there is one)
can simply contain "call file2.bat par1 parm2" and can be executed by the normal CMD.EXE,
while the "file2.bat" can then contain:
#set db2cmd="C:\Program Files\IBM\SQLLIB\BIN\db2cmd.exe"
#if "%DB2CLP%"=="" %db2cmd% /w /c /i "%0" %* && #goto :EOF
#rem If db2cmd.exe is on the system PATH then you can omit the set db2cmd line.
db2 connect to dbname user username using psw
...rest of script...
...you can use db2 CLP commands directly
The first line sets a variable to contain the fully qualified pathname to the db2cmd.exe executable. This is the default path so you may need to change the pathname to match your environment, and you can omit this if you are certain that db2cmd.exe will always be on the system path.
The second line tests if the script is running under db2cmd.exe (in which case the DB2CLP environment
variable will be set). If the script is not running under db2cmd.exe then the script runs itself
under db2cmd.exe passing on the same command-line parameters. If the script is already running under db2cmd.exe then continue to the next line.

Related

use root cmd window to execute commands in new cmd window

i'm trying to make a batch script for running my Java files. I've found out that there is no way to prevent auto-closure of a batch script(except using pause keyword, tho it just waits for key press). I've also discovered that starting a new window will cause only main windows to close, not the new one too so i want a way that the command SET /P file=Java file: is executed in the new window(I got the new window by using the start keyword. Is there any way to accomplish this without downloading other softwares? this is the code i came up with yet:
cd "C:\Users\DEVDHRITI\Desktop\Files&Folders\HMMMMM\programs\java programmes"
set /P file=Java file to execute:
java %file%^.jar
start
I guess you're looking for that :
cd "C:\Users\DEVDHRITI\Desktop\Files&Folders\HMMMMM\programs\java programmes"
start cmd /V:ON /K "#set /P "file=Java file to execute: " && java -jar !file!^.jar"
EDIT: Using expansion with /V and use of /K instead of /C to keep the cmd windows open.
Explanations : To launch a console process in another windows and keep it open after the end of this process console we launch another cmd process with the start command. We use /V:ON to use delayed expansion by default, meaning modified variables (like the one we prompt, %file%) will be expanded on the fly with ! (so !file! instead of %file%). We use /K to tell to this cmd process to not close when provided commands end. To this cmd process, we provide the following commands :
#set /P "file=Java file to execute: "
This one will ask for the jar filename (without extension) to launch.
The # means "do not echo the command itself on the console stdout" for a nice display.
java -jar %file%^.jar
This one launch the java interpreter (JVM) with the filename of a jar file to execute through the -jar parameter, filename build from the previous prompt and the .jar extension. The ^ here escapes the ., it seems not useful here but maybe your script/env requires it.
We link the both commands with && which means : _if left command from && is successful (it exits with ERRORLEVEL 0) then execute the right command from &&.

Removing the current working directory from the path

I'm working in Windows and would like to know if there is a way to remove the current working directory from the path? I understand that this is the default behavior in PowerShell, but I need it to work in batch or at the Windows command-line.
In UNIX, I would just make sure that my $PATH variable not contain .. Is there any way to accomplish this in batch? This is the current behavior:
H:\tmp>dir
Volume in drive H has no label.
Volume Serial Number is E29C-7B61
Directory of H:\tmp
04/27/2018 10:39 AM <DIR> .
04/27/2018 10:39 AM <DIR> ..
04/27/2018 10:40 AM 37 dwk.bat
1 File(s) 37 bytes
2 Dir(s) 987,995,770,880 bytes free
H:\tmp>dwk.bat
dwk.bat has been run.
H:\tmp>
This is the desired behavior:
H:\tmp>dwk.bat
'dwk.bat' is not recognized as an internal or external command,
operable program or batch file.
H:\tmp>.\dwk.bat
dwk.bat has been run.
H:\tmp>
Thanks.
I recommend first reading the answers on Stack Overflow questions:
Where is "START" searching for executables?
What is the reason for '...' is not recognized as an internal or external command, operable program or batch file?
Many thanks to eryksun because of this answer would not exist without his comment on above referenced answer.
Next I recommend reading the Microsoft Developer Network (MSDN) articles:
Naming Files, Paths, and Namespaces
NeedCurrentDirectoryForExePath function
The question can be answered with: Yes, it is possible for desktop applications and batch files on
Windows Vista and all later Windows client versions and
Windows Server 2003 and all later Windows Server versions.
An environment variable with name NoDefaultCurrentDirectoryInExePath must be defined with any value to prevent execution of a script (.bat, .cmd, .vbs, ...) or an application (.com, .exe) stored in current directory without explicitly using .\ as required on Unix/Linux.
The environment variable NoDefaultCurrentDirectoryInExePath can be defined as system variable to turn off searching in current directory for a script or application for all accounts on this machine. But this is surely no good idea as it will result definitely in many applications including installers and uninstallers won't work anymore correct.
The environment variable NoDefaultCurrentDirectoryInExePath can be defined as user variable to turn off searching in current directory for a script or application for processes using this account. But this is surely also no good idea.
But it can make sense to set the environment variable NoDefaultCurrentDirectoryInExePath as local variable in some use cases to turn off searching in current directory for a script or application without explicitly using .\ on Windows versions with kernel function NeedCurrentDirectoryForExePath which cmd.exe calls before searching for a script file or application not containing a backslash \ (or a forward slash /) in file name string.
Example:
#echo off
pushd "%TEMP%"
set "NoDefaultCurrentDirectoryInExePath=0"
echo #echo %%0 executed successfully.>Test1.bat
echo Calling Test1.bat ...
call Test1.bat
echo Calling .\Test1.bat ...
call .\Test1.bat
echo Starting Test1.bat ...
start /wait Test1.bat ^& timeout 5
set "NoDefaultCurrentDirectoryInExePath="
echo Calling again Test1.bat ...
call Test1.bat
del Test1.bat
popd
pause
This batch file executed from within a command prompt window results in output of current console window:
Calling Test1.bat ...
'Test1.bat' is not recognized as an internal or external command,
operable program or batch file.
Calling .\Test1.bat ...
.\Test1.bat executed successfully.
Starting Test1.bat ...
Calling again Test1.bat ...
Test1.bat executed successfully.
Press any key to continue . . .
And during execution of this batch file a second console window is opened with output:
"%TEMP%\Test1.bat" executed successfully.
This second console window is closed automatically after 5 seconds.
The environment variable NoDefaultCurrentDirectoryInExePath is defined with value 0 after setting directory for temporary files as current directory with pushing current directory path on stack. The variable value does not matter because of evaluated is only existence of environment variable and not its value.
Next another batch file with name Test1.bat is created in directory for temporary files which is usually not write-protected for current user as this would cause lots of troubles.
The first approach to call Test1.bat without any path fails because of environment variable NoDefaultCurrentDirectoryInExePath is defined in local environment.
The second call of Test1.bat with relative path .\ is successful despite existence of the environment variable.
The command START ignores NoDefaultCurrentDirectoryInExePath as proven by this batch file.
Then the environment variable NoDefaultCurrentDirectoryInExePath is deleted to restore original Windows behavior.
The second approach to call Test1.bat without any path is successful now.
Finally the created Test1.bat is deleted and initial current directory is restored as current directory.
It is of course not possible to prevent execution of command DIR which is not a script file or an executable. It is an internal command of cmd.exe – Windows Command Processor – respectively of powershell.exe – Windows PowerShell.

Why is an argument passed to a Perl script not working on running it from within a batch file?

I wrote a batch called pippo.bat for launching a program with an argument. However, it fails in getting such argument. In other words, it acts as I don't give it any argument.
pippo.bat
#echo off
mode con: cols=150 lines=5000
title Link Setting
echo.
echo LINK SETTING
echo.
cd /d E:\Program Files (x86)\pippo\bin
pippoedit.ovpl –f C:\Work\pippo.xml
pause
What's wrong?
You're executing pippoedit.ovpl –f C:\Work\pippo.xml.
Note the extension, .ovpl, which isn't registered as an executable. This means you let the OS figure out and start the application associated with that extension, and start that program with that filename as argument. Here, a small repro:
#echo off
foo.txt bar.txt
This starts Notepad or whichever application is associated with the .txt extension and displays the file foo.txt.
When you do this, Windows doesn't do anything with the arguments beyond the first. Instead you should start the application directly, and pass it the arguments:
pippoedit.exe pippoedit.ovpl –f C:\Work\pippo.xml
Or whatever the executable is called.

PSEXEC without terminate batch job

I'm trying to make my windows service run bat file with
psexec -accepteula -h -i 1 myapp.exe --p1 lala --p2 lalala
but closing the myapp cmd window results with "Terminate batch job y/n" question and service doesn't get the fact that it needs to restart itself.
In order to ignore this question, I googled and tried add
< nul
to the end of the command, but that didn't help. I assume that psexec doesn't get the fact, that "< nul" part is not for myapp but for psexec itself.
So how can I make my psexec finish without any questions about terminating batch job?
One way to do it is to create a SECOND batch file. The second file will call the first batch file and it will append "< nul".
For example, say you had a batch file which contained the following line:
python manage.py runserver
Name this file something like file1.bat
Then create a second batch file which contains the line:
file1.bat < nul
Name the second file something like file2.bat Then, execute the second file from that point on in order to call your program.
This worked for me in a Windows 10 environment. Good luck.

Passing parameters to psql.exe

I want to launch psql.exe from an application. The user locates the script, so it could be anywhere on his disk, and the application just feeds that script to psql. That's about it.
What's the correct command line for that ?
I tried this with no success
"C:\Program Files\PostgreSQL\9.1\bin\psql.exe" TEST SYSADM -f "C:\Documents and Settings\Administrateur\Mes documents\TD6.0\FETCHING\install.sql"
I tried with quotes, without the quotes, none worked, it's just ignoring the arguments (tried this on cmd.exe)
C:\Documents and Settings\Administrateur>"C:\Program Files\PostgreSQL\9.1\bin\psql.exe" TEST SYSADM -f "C:\Documents and Settings\Administrateur\Mes documents\TD6.0\FETCHING\install.
sql"
psql: warning: extra command-line argument "-f" ignored
psql: warning: extra command-line argument "C:\Documents and Settings\Administrateur\Mes documents\TD6.0\FETCHING\install.sql" ignored
Password for user SYSADM:
Yes, if the script is in the same directory as psql.exe, and if I CD first to where psql.exe is installed, that means no quotes, no absolute paths and it works fine. However, in my case, I want the application to work on any windows installation, that means psql.exe could be anywhere and the sql script also could be anywhere. I still want the script to be fed to psql.exe.
Try this:
"C:\Program Files\PostgreSQL\9.1\bin\psql.exe" -f "C:\Documents and Settings\Administrateur\Mes documents\TD6.0\FETCHING\install.sql" TEST SYSADM
Save the commands below as a BATch file (install.bat, etc).
Note the 'defaultValueHere'. You can set the default value in case your user skips the entry.
SET installScript=defaultValueHere
SET /P server="Enter the install script location [%installScript%]: "
ECHO you typed %installScript%
PAUSE
"C:\Program Files\PostgreSQL\9.1\bin\psql.exe" TEST SYSADM -f %installScript%
Instruct the user to launch the installation from the install.bat file. Also see my answer on passing parameters to the SQL script.

Resources