英文:
Check for text variable substring in environment variable
问题
Here is the translated content you requested:
尝试创建一个批处理文件,通过调用 sqlcmd.exe
运行 SQL 脚本,我正在尝试让批处理文件在执行之前自动检测 exe
文件的存在并将其添加到 %PATH%
中。我可以保证它会出现在主机上的某个地方,但不确定在哪里。
查看 Stack Overflow 上的许多 示例,这表明检测字符串 A 是否在字符串 B 中的最稳健方法是使用 echo
命令并使用管道 findstr
命令来考虑大小写不敏感等因素。
考虑到这一点,我在我的批处理文件中有以下内容:
@echo off
REM 确保我们可以找到 SQL 解释器
echo 正在检查 SqlCmd.exe,请稍候...
setlocal EnableDelayedExpansion
for /f "delims=" %%F in ('dir "%programfiles%\sqlcmd.exe" /s/b') do (
set filepath=%%~dpF
echo "Found SQL interpreter in: !filepath!"
REM 它是否已经在 PATH 中?
echo %path% | findstr /c:"!filepath!" 1>nul
if errorlevel 1 (
echo "SqlCmd 不在当前环境变量 PATH 中,正在设置..."
set path=%path%;!filepath!
)
)
并且输出如下:
正在检查 SqlCmd.exe,请稍候...
\Microsoft 在此时间点上是意外的。
尽管输出中没有出现 Found SQL interpreter in:
文本,但实际问题似乎出现在下一行可执行代码上(通过删除它并运行进行测试):
echo %path% | findstr /c:"!filepath!" 1>nul
它似乎正在echo
整行并执行,而不是将 %path%
输出并进行 findstr
管道处理。我尝试添加引号但没有效果。
我几乎完成了,但似乎还需要一步编码或调整才能使其正常工作。
更新 1
我测试机器上的 PATH
变量内容如下:
C:\Program Files\Common Files\Oracle\Java\javapath;C:\Program Files\Microsoft MPI\Bin\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\Microsoft SQL Server0\Tools\Binn\;C:\Program Files\Microsoft SQL Server0\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server0\DTS\Binn\;C:\Program Files\Microsoft SQL Server0\DTS\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC0\Tools\Binn\;C:\Program Files\Microsoft SQL Server0\Tools\Binn\;C:\Program Files\dotnet\;C:\ProgramData\chocolatey\bin;C:\Program Files (x86)\Windows Kits\Windows Performance Toolkit\;C:\Program Files\Git\cmd;C:\Users\User\.dotnet\tools;C:\Program Files\Java\jdk-17.0.3.1\bin;C:\Users\User\AppData\Local\Programs\Microsoft VS Code\bin;C:\Program Files\Azure Data Studio\bin
英文:
While trying to create a batch file that runs a SQL script by calling out to sqlcmd.exe
, I'm trying to get the batch file to detect for the presence of the exe and add it to %PATH%
automatically before executing. I can guarantee that it will be somewhere on the host but not where.
Looking at the many examples on SO, this suggests that the most robust way of detecting if string A is in string B is to echo
out and pipe to findstr
to account for case insensitivity, etc.
With this in mind, I have the following in my batch file;
@echo off
REM Ensure we can find the sql interpreter
echo Checking for SqlCmd.exe, please wait...
setlocal EnableDelayedExpansion
for /f "delims=" %%F in ('dir "%programfiles%\sqlcmd.exe" /s/b') do (
set filepath=%%~dpF
echo "Found SQL interpreter in: !filepath!"
REM is it part of the PATH already?
echo %path% | findstr /c:"!filepath!" 1>nul
if errorlevel 1 (
echo "SqlCmd is not part of the current ENVAR PATH, setting..."
set path=%path%;!filepath!
)
)
And has the following output;
Checking for SqlCmd.exe, please wait...
\Microsoft was unexpected at this time.
Despite the text Found SQL interpreter in:
not appearing in the output, the actual issue seems to be in the next executable line (tested by removing it and running):
echo %path% | findstr /c:"!filepath!" 1>nul
It seems to be echo
ing out the whole line and executing rather than echo
ing out the %path%
and piping to findstr
. I've tried adding quotes to no effect.
I'm almost there but missing an encoding step/tweak to get this to work.
Update 1
The PATH
variable contents on my test machine is;
C:\Program Files\Common Files\Oracle\Java\javapath;C:\Program Files\Microsoft MPI\Bin\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\Microsoft SQL Server0\Tools\Binn\;C:\Program Files\Microsoft SQL Server0\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server0\DTS\Binn\;C:\Program Files\Microsoft SQL Server0\DTS\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC0\Tools\Binn\;C:\Program Files\Microsoft SQL Server0\Tools\Binn\;C:\Program Files\dotnet\;C:\ProgramData\chocolatey\bin;C:\Program Files (x86)\Windows Kits\Windows Performance Toolkit\;C:\Program Files\Git\cmd;C:\Users\User\.dotnet\tools;C:\Program Files\Java\jdk-17.0.3.1\bin;C:\Users\User\AppData\Local\Programs\Microsoft VS Code\bin;C:\Program Files\Azure Data Studio\bin
答案1
得分: 0
以下是翻译好的部分:
经过Magoo和Mofi的非常有帮助的建议以及一些实验,我调整了逻辑,使其
- 正确考虑了大小写(我漏掉了
/I
) - 修复了语法问题,从
/s/b
改为/s /b
- 添加了新的
setlocal EnableExtensions
标志 - 将循环变量更改为
J
我也尝试了其他建议,但它们对批处理文件的运行没有实际影响(除了一些微妙的差异)。然后我遇到了一个障碍;
set path="%path;%%~dpF"
这导致%PATH%
有一个前导和尾随的"
,这破坏了对%PATH%
引用的所有内容。省略"
意味着SET
导致原始错误。
相反,我放弃了尝试设置%PATH%
,直接使用了对SqlCmd.exe
的引用。最终的批处理文件如下;
@echo off
REM 确保我们能找到sql解释器
echo 正在检查是否存在SqlCmd.exe,请稍候...
setlocal EnableExtensions
setlocal EnableDelayedExpansion
for /f "delims=" %%J in ('dir "%programfiles%\sqlcmd.exe" /s /b') do (
echo 在 %%~dpJ 找到SqlCmd
set sqlcmd="%%J"
goto 退出
)
:退出
%sqlcmd% /?
对于仍然希望设置%PATH%
变量并阅读有关变量扩展等的人,Mofi的链接如下以方便参考;
- Windows命令解释器(CMD.EXE)如何解析脚本?
- 调试批处理文件
- 问题7:将字母ADFNPSTXadfnpstx用作循环变量
- 如何在批处理文件中仅在Windows上设置PATH环境变量一次?
- 如何检查%PATH%中是否存在目录(如果要设置
%PATH%
,这是您要找的页面)
英文:
After very helpful suggestions from Magoo and Mofi and some experimentation, I tweaked the logic such that it was
- Correctly accounting for case (I had ommitted the
/I
) - Fixed the sytax issue of
/s/b
to/s /b
- Added the new
setlocal EnableExtensions
flag - Changing the loop variable to
J
I had also applied the other suggestions but they had no defacto effect (valid subtlties and distinctions aside) on the running of the batch file. I then hit the hurdle of;
set path="%path;%%~dpF"
This resulted in %PATH%
having a leading and trailing "
which broke all references to anything %PATH%
was referencing. Leaving out the "
meant that the SET
resulted in the original error.
Instead I ditched my attempt to set %PATH%
entirely and just used the found reference to SqlCmd.exe
directly. The final batch file is like so;
@echo off
REM Ensure we can find the sql interpreter
echo Checking for SqlCmd.exe, please wait...
setlocal EnableExtensions
setlocal EnableDelayedExpansion
for /f "delims=" %%J in ('dir "%programfiles%\sqlcmd.exe" /s /b') do (
echo SqlCmd found at %%~dpJ
set sqlcmd="%%J"
goto exit
)
:exit
%sqlcmd% /?
For those looking to still set the %PATH%
variable, and read up on variable expansion, etc, Mofi's links are listed below for convenience;
-
How does Windows Commadn Interpreter (CMD.EXE) parse scripts?
-
Issue 7: Usage of letter ADFNPSTXZadfnpstxz as loop variables
-
How to set PATH environmetn variable in batch file only once on Windows?
-
How to check if directory exists in %PATH% (this is the page you're looking for if you want to set
%PATH%
)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论