CMD 'Where' function

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
SIMMS7400
Posts: 546
Joined: 07 Jan 2016 07:47

CMD 'Where' function

#1 Post by SIMMS7400 » 26 Jul 2016 11:33

Hi Guys -

I use the following code a lot to locate applications to be able to display the full path so I can then execute it:

Code: Select all

SET FIND_SQLCMD=%cd:~0,3%FIND_SQLCMD.txt
Where sqlcmd.exe>%FIND_SQLCMD%
SET /P  SQL_CMD_PATH=<%FIND_SQLCMD%
DEL %FIND_SQLCMD%


Is there a similar method to use to find a specific *cmd file to return the full path? I'm having trouble return a full path to a specific batch file I'm searching for the in %cd:~0,3% directory.

Thanks!

Squashman
Expert
Posts: 4488
Joined: 23 Dec 2011 13:59

Re: CMD 'Where' function

#2 Post by Squashman » 26 Jul 2016 11:44

Not quite following your explanation. Could you provide an example?

SIMMS7400
Posts: 546
Joined: 07 Jan 2016 07:47

Re: CMD 'Where' function

#3 Post by SIMMS7400 » 26 Jul 2016 12:30

Surely!

So, I need to jump across servers quite regularly to execute certain utilities. Therefore, I use the code above to find a particular .exe I'm searching for.

Then, it outputs the full path include exe name to a .txt file. I then read that path back in and SET it in a variable I can use it to execute it.

For instance:

This script is placed on every server where I need to execute a utilities:

Code: Select all

@ECHO OFF

SET FIND_SQLCMD=%cd:~0,3%FIND_SQLCMD.txt
Where %1.exe>%FIND_SQLCMD%
SET /P  SQL_CMD_PATH=<%FIND_SQLCMD%
DEL %FIND_SQLCMD%

CALL "%SQL_CMD_PATH%" -v DATASOURCE ="%2" -S %3 -U %4 -P %5 -i %6



So then %SQL_CMD_PATH% is set with:

C:\Program Files\Microsoft SQL Server\100\Tools\Binn\SQLCMD.EXE


The params are passed in from a calling batch file from my main server. (I'm using PSEXEC). The process will now execute.

So my question is, since Where function only works with .exe's, can anyone suggest a piece of code the searches for a specific batch file and then returns the full path for me? I have a lot of out of the box utilities in various locations of the file systems so this method would be quickest instead of me trying to find and set the paths as variables.

Thanks!

aGerman
Expert
Posts: 4724
Joined: 22 Jan 2010 18:01
Location: Germany

Re: CMD 'Where' function

#4 Post by aGerman » 26 Jul 2016 13:13

I guess you want to simplify the assignment of SQL_CMD_PATH. In that case you could process the output of WHERE in a FOR /F loop.
E.g.

Code: Select all

for /f "delims=" %%i in ('where notepad.exe') do set "notepad_path=%%i"

Just replace notpad.exe and notepad_path with whatever you want.

Regards
aGerman

Squashman
Expert
Posts: 4488
Joined: 23 Dec 2011 13:59

Re: CMD 'Where' function

#5 Post by Squashman » 26 Jul 2016 13:25

SIMMS7400 wrote:So my question is, since Where function only works with .exe's,


Where does it say that in the HELP file????? PUN INTENEDED

Code: Select all

H:\>where /R H:\ temp.txt
H:\temp.txt
H:\mount\temp.txt
H:\temp\temp.txt


Code: Select all

H:\>where /?

WHERE [/R dir] [/Q] [/F] [/T] pattern...

Description:
    Displays the location of files that match the search pattern.
    By default, the search is done along the current directory and
    in the paths specified by the PATH environment variable.

Parameter List:
    /R       Recursively searches and displays the files that match the
             given pattern starting from the specified directory.

    /Q       Returns only the exit code, without displaying the list
             of matched files. (Quiet mode)

    /F       Displays the matched filename in double quotes.

    /T       Displays the file size, last modified date and time for all
             matched files.

    pattern  Specifies the search pattern for the files to match.
             Wildcards * and ? can be used in the pattern. The
             "$env:pattern" and "path:pattern" formats can also be
             specified, where "env" is an environment variable and
             the search is done in the specified paths of the "env"
             environment variable. These formats should not be used
             with /R. The search is also done by appending the
             extensions of the PATHEXT variable to the pattern.

     /?      Displays this help message.

  NOTE: The tool returns an error level of 0 if the search is
        successful, of 1 if the search is unsuccessful and
        of 2 for failures or errors.

Examples:
    WHERE /?
    WHERE myfilename1 myfile????.*
    WHERE $windir:*.*
    WHERE /R c:\windows *.exe *.dll *.bat
    WHERE /Q ??.???
    WHERE "c:\windows;c:\windows\system32:*.dll"
    WHERE /F /T *.dll

H:\>

Aacini
Expert
Posts: 1927
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: CMD 'Where' function

#6 Post by Aacini » 26 Jul 2016 13:36

SIMMS7400 wrote:... since Where function only works with .exe's,


No. "Where" command also may seek for .bat files. As a matter of fact, it may seek for any type of file; just put the whole filename and extension.

Anyway, this form of "for" command do a process equivalent of "Where" command:

Code: Select all

for %%a in (sqlcmd.exe) do set "SQL_CMD_PATH=%%~$PATH:a"

Antonio

Squashman
Expert
Posts: 4488
Joined: 23 Dec 2011 13:59

Re: CMD 'Where' function

#7 Post by Squashman » 26 Jul 2016 13:43

Aacini wrote:Anyway, this form of "for" command do a process equivalent of "Where" command:

Code: Select all

for %%a in (sqlcmd.exe) do set "SQL_CMD_PATH=%%~$PATH:a"

Antonio

But if the file is in the current directory it will not find it, but the where command will because it searches the current directory and the path.

SIMMS7400
Posts: 546
Joined: 07 Jan 2016 07:47

Re: CMD 'Where' function

#8 Post by SIMMS7400 » 26 Jul 2016 14:14

Ah - well there you go!

Go it!

Code: Select all

@ECHO OFF

SET FIND_UTIL_BAT=%cd:~0,3%FIND_UTIL_BAT.txt
Where /R %cd:~0,3% Utility.bat>%FIND_UTIL_BAT%
SET /P  UTIL_PATH=<%FIND_UTIL_BAT%

ECHO %UTIL_PATH%

PAUSE


Output:

C:\Oracle\Middleware\EPMSystem11R1\common\utilities\LCM\11.1.2.0\bin\Utility.bat
C:\Oracle\Middleware\user_projects\epmsystem1\bin\Utility.bat


Is there a way to add additional code to only read back in a certain line? For instance, this output gives me two locations. While either util will be ok, I like to use the Utility.bat on line 2. Since this will read back in the first line, is there anyway to tell it to read back in the line with 'user_projects' on it?

Thank you for all your help folks!
Last edited by SIMMS7400 on 26 Jul 2016 14:26, edited 1 time in total.

douglas.swehla
Posts: 75
Joined: 01 Jun 2016 09:25

Re: CMD 'Where' function

#9 Post by douglas.swehla » 26 Jul 2016 14:26

For the SQLCMD utility, why do you need to find the path at all? The "C:\Program Files\Microsoft SQL Server\###\Tools\Binn" directory is normally added to the PATH variable at SQL Server installation, so once you've connected to the remote machine, you should be able to just run it normally.

As a general solution, if you've got a bunch of utilities on a bunch of servers, consolidate them into a Utilities folder on each machine, and add that folder to the PATH variable. If that's impractical, there's still no need to save the path to a variable, as you can use it immediately within the FOR command that everyone else has already suggested.

Code: Select all

call find_run.bat "path\to\search_directory" "my_batch.cmd" arg1 arg2 arg3

Code: Select all

::find_run.bat
for /f "tokens=* delims=" %%F in ('where /r "%~1" "%~2"') do ("%%F" %3 %4 %5)


To accept an arbitrary number of arguments to the remote command, it gets a little more complicated:

Code: Select all

::find_run_args.bat
set "all_args=%*"
call set "cmd_args=%%all_args:*%2=%%"
for /f "tokens=* delims=" %%F in ('where /r "%~1" "%~2"') do ("%%F" %cmd_args%)

douglas.swehla
Posts: 75
Joined: 01 Jun 2016 09:25

Re: CMD 'Where' function

#10 Post by douglas.swehla » 26 Jul 2016 14:54

SIMMS7400 wrote:Is there a way to add additional code to only read back in a certain line? For instance, this output gives me two locations. While either util will be ok, I like to use the Utility.bat on line 2. Since this will read back in the first line, anyway to grab the second?


You're taking kind of a roundabout approach to this. There's no need to create, read, and delete a file when you can use the value directly. Instead of finding one line in a file, just get one line in the first place, and store it directly into a variable. A few people have already pointed out that a FOR loop will do this for you.

The command where /r "C:\Oracle\Middleware\user_projects" "Utility.bat" will return only the second line, because we've used the /R switch to tell WHERE to start looking in the right place.

Code: Select all

@ECHO OFF

FOR /F "TOKENS=* DELIMS=" %%F IN ('WHERE /R "C:\Oracle\Middleware\user_projects" Utility.bat') DO SET "UTIL_PATH=%%F"

ECHO %UTIL_PATH%

PAUSE


Of course, this means you'll need to pass both the starting directory and the file name as arguments to the script. My earlier answer addresses that. It also addresses running the command immediately, instead of storing it into a variable first.

It's worth noting that FOR will iterate over each result returned. In an instance where the DO portion is a SET command, this means the variable will be set as many times as there are results, with the last one being the one that sticks. If we ran for /f "tokens=* delims=" %%F in ('where /r %cd:~0,3% Utility.bat') do set "util_path=%%F", the variable util_path would first be set to C:\Oracle\Middleware\EPMSystem11R1\common\utilities\LCM\11.1.2.0\bin\Utility.bat, and then to C:\Oracle\Middleware\user_projects\epmsystem1\bin\Utility.bat. In this specific case, that suits your needs, but it's often hard to be certain the results will be returned in the order you want, so it's best to not count on that. Instead, set up the command (piping through one or more FIND commands, if necessary) so that only the result you want makes it through.

SIMMS7400
Posts: 546
Joined: 07 Jan 2016 07:47

Re: CMD 'Where' function

#11 Post by SIMMS7400 » 26 Jul 2016 17:31

Hi Everyone -

Thank you so much for all the help!! Much appreciated!

@ Douglas -

That's great! So, the reason for my more generic 'Where' syntax was because the drive letter could change across environments. Therefore, I wanted to be able to capture that and not hard code anything. However as you've seen, I needed to spool it to a txt file and then bring back in the correct path.

Is there anywhere to add syntax to your solution that dynamically populates the drive letter so I dont need to hard code that? Or am I limited to hard coding the drive letter?

Thanks!!

SIMMS7400
Posts: 546
Joined: 07 Jan 2016 07:47

Re: CMD 'Where' function

#12 Post by SIMMS7400 » 26 Jul 2016 17:53

I assume this will not work because in the event I execute this script in a different directory than Utility.bat exists, it will only return current directory letter and thus fail. Is that correct? Hence, thats why I need to essentially find "Utility" bat, return the drive letter, then use the Oracle\Middleware\user_projects path.

Code: Select all

@ECHO OFF

FOR /F "TOKENS=* DELIMS=" %%F IN ('WHERE /R "%cd:~0,3%Oracle\Middleware\user_projects" Utility.bat') DO SET "UTIL_PATH=%%F"

ECHO %UTIL_PATH%

PAUSE

Squashman
Expert
Posts: 4488
Joined: 23 Dec 2011 13:59

Re: CMD 'Where' function

#13 Post by Squashman » 26 Jul 2016 18:31

If you happened to read the HELP file that I so graciously posted for you to read, you may notice that it also searches for the file in all the directories listed in your path variable. So if it finds it there, that could be the directory it assigns to your variable.

douglas.swehla
Posts: 75
Joined: 01 Jun 2016 09:25

Re: CMD 'Where' function

#14 Post by douglas.swehla » 26 Jul 2016 20:26

I suspect we're trying to solve the wrong problem. There are a number of steps we're not seeing and assumptions that aren't addressed. I think your general goal is to run commands on remote systems, and that should usually be possible without intermediate scripts on the remote system.

For the SQLCMD task, I'd like to see a copy of the script you're running from the main server, and an example of a command you use to call it. Where does PSEXEC come into play?

For the cmd/bat task, please give an example of a remote script you're trying to run, and how you've been approaching the problem so far.

I have too many questions about why you're approaching things a certain way, and I think this might help answer some of them before we go chasing rabbits.

douglas.swehla
Posts: 75
Joined: 01 Jun 2016 09:25

Re: CMD 'Where' function

#15 Post by douglas.swehla » 26 Jul 2016 20:35

SIMMS7400 wrote:I assume this will not work because in the event I execute this script in a different directory than Utility.bat exists, it will only return current directory letter and thus fail. Is that correct? Hence, thats why I need to essentially find "Utility" bat, return the drive letter, then use the Oracle\Middleware\user_projects path.

Code: Select all

@ECHO OFF

FOR /F "TOKENS=* DELIMS=" %%F IN ('WHERE /R "%cd:~0,3%Oracle\Middleware\user_projects" Utility.bat') DO SET "UTIL_PATH=%%F"

ECHO %UTIL_PATH%

PAUSE


The current directory (%CD%) and the script location (%~dp0) are different animals. The snippet "%cd:~0,3%" will expand to the drive letter that you chose (or accepted as default) when connecting to the remote machine, or whichever one you've navigated to since then. This is entirely independent of where the script is located. If you want to base the search around the script location, that can be done.

I think the code above should work. Have you tried it? What was the result?

Post Reply