文章目录
用WHERE命令可以在命令行搜索文件
概述
想确认PATH变量中是否存在某个指定的程序(具体是在PATH环境变量中给出的哪个路径底下?).
开始不知道windows有where这个命令, 还自己花了2个小时写了一个小程序.
后来翻到一个cmake.bat, 才发现, 人家使用WHERE命令直接来搜索一个程序是否存在.
看了一下WHERE命令的帮助, 功能真全啊.
WHERE命令默认是在当前目录和PATH环境变量中搜索, 也可以指定路径来搜索, 还支持通配符.
where命令在winxp中没有, 在win7/win10中都有这个命令
bash
C:\Users\chenx>where /?
WHERE [/R dir] [/Q] [/F] [/T] pattern...
描述:
显示符合搜索模式的文件位置。在默认情况下,搜索是在当前目录和 PATH
环境变量指定的路径中执行的。
参数列表:
/R 从指定目录开始,递归性搜索并显示符合指定模式的文件。
/Q 只返回退出代码,不显示匹配文件列表。(安静模式)
匹配文件。(安静模式)
/F 显示所有相配文件并用双引号括上。
/T 显示所有相配文件的文件的文件。
pattern 指定要匹配的文件的搜索模式。通配符 * 和 ? 可以用在模式中。
也可以指定 "$env:pattern" 和 "path:pattern" 格式; 其中
"env" 是环境变量,搜索是在 "env" 变量的指定的路径中执行的。
这些格式不应该跟 /R 一起使用。此搜索也可以用将 PATHEXT 变
量扩展名附加于此模式的方式完成。
/? 显示此帮助消息。
注意: 如果搜索成功,此工具返回错误级别 0; 如果不成功,返回 1; 如果失
败或发生错误,返回 2。
示例:
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
笔记
没用的小程序
刚开始, 自己不知道, 写了一个小程序. 从PATH环境变量中搜索指定的程序是否存在.
比MS家提供的WHERE命令low太多了.
虽然做了一个没用的实验, 也留着以后看.
通过实验, 有以下收获.
- _access()支持带空格的路径
c
// getExePathNameFromEnvPath.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <io.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <map>
typedef std::map<int, const char*> MAP_ENV;
bool processEnvPath(const char* pszEnvPath, MAP_ENV& map_env, bool dispDebugInfo);
bool processPathValue(int sn, const char* pszPath, MAP_ENV& map_env, bool dispDebugInfo);
bool ReplaceEnv(const char* pszSrc, char*& pszDst, int& lenDst); // 需要调用者自己释放pszDst
bool IsFileExist(char* pszPathName);
/*!
cmd line = THE_EXE cmake.exe cmake.cmd cmake.bat cmake.com
run result
[49] - error : %JAVA_HOME%\bin
find EXE from PATH [1] - C:\CMake\bin\cmake.exe
find EXE from PATH [2] - C:\Program Files (x86)\IncrediBuild\cmake.bat
*/
/*
正好翻到一个cmake.bat, 里面用where来检测cmake在哪里, win10中可用
where cmake
C:\CMake\bin\cmake.exe
// 默认是在当前路径和%PATH%中查找, 可以带通配符
C:\Users\chenx>where cmake.*
C:\CMake\bin\cmake.exe
C:\Program Files (x86)\IncrediBuild\cmake.txt
// 可以在指定目录下搜索指定的文件
WHERE /R c:\windows *.exe *.dll *.bat
// 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
*/
/*!
去winxp下看了一下, 并没有where这个命令
在win7/win10中都有这个命令
在win10中的位置如下:
C:\Users\chenx>where where*.*
C:\Windows\System32\where.exe
*/
int main(int argc, char** argv)
{
MAP_ENV map_env;
MAP_ENV::iterator it;
int i = 0;
const char* pszEnvPath = ::getenv("PATH");
char szBuf[_MAX_PATH];
int iFindPos = 0;
do {
if (argc < 2)
{
printf("function : to find argv[x]'s prog on %%PATH%%\n");
printf("usage : THE_EXE prog_to_find1 prog_to_find2 ...\n");
break;
}
// insert %path%'s value item to map
processEnvPath(pszEnvPath, map_env, false);
// use map_env
for (i = 1; i < argc; i++)
{
for (it = map_env.begin(); it != map_env.end(); it++)
{
assert(NULL != it->second);
memset(szBuf, 0, sizeof(szBuf));
strcpy(szBuf, it->second);
if (szBuf[strlen(szBuf) - 1] != '\\')
{
szBuf[strlen(szBuf)] = '\\';
}
strcat(szBuf, argv[i]);
// find szBuf is exist?
if (IsFileExist(szBuf))
{
printf("find EXE from PATH [%d] - %s\n", ++iFindPos, szBuf);
}
}
}
// free map_env
for (it = map_env.begin(); it != map_env.end(); it++)
{
if (NULL != it->second)
{
delete[] it->second;
it->second = NULL;
}
}
map_env.clear();
} while (false);
system("pause");
}
bool IsFileExist(char* pszPathName)
{
bool b_rc = false;
// find EXE from PATH [2] - C:\Program Files (x86)\IncrediBuild\cmake.bat
// _access 支持带空格的路径
do {
assert(NULL != pszPathName);
if (0 != _access(pszPathName, 0))
{
break;
}
b_rc = true;
} while (false);
return b_rc;
}
bool processEnvPath(const char* pszEnvPath, MAP_ENV& map_env, bool dispDebugInfo)
{
bool b_rc = false;
char* pszBuf = NULL;
char* pszFind = NULL;
char* pszFindRc = NULL;
int len = 0;
int i = 0;
do {
if (NULL == pszEnvPath)
{
break;
}
len = (int)strlen(pszEnvPath);
if (len <= 0)
{
break;
}
pszBuf = new char[len + 1];
pszBuf[len] = '\0';
strcpy(pszBuf, pszEnvPath);
pszFind = pszBuf;
do {
i++;
// printf("i = %d\n", i);
if (67 == i)
{
i = i; // for debug
}
pszFindRc = strchr(pszFind, ';');
if (NULL == pszFindRc)
{
// 最后一个
processPathValue(i, pszFind, map_env, dispDebugInfo);
break;
}
else {
pszFindRc[0] = 0x00;
processPathValue(i, pszFind, map_env, dispDebugInfo);
pszFindRc[0] = ';';
if (0x00 == pszFindRc[1])
{
break;
}
pszFind = pszFindRc + 1;
}
} while (true);
} while (false);
if (NULL != pszBuf)
{
delete[] pszBuf;
pszBuf = NULL;
}
return b_rc;
}
bool processPathValue(int sn, const char* pszPath, MAP_ENV& map_env, bool dispDebugInfo)
{
bool b_rc = false;
char* pszTmp = NULL;
int lenTmp = 0;
do {
if (NULL == pszPath)
{
break;
}
if (dispDebugInfo)
{
printf("[%d] %s\n", sn, pszPath);
}
if (NULL == strchr(pszPath, '%'))
{
// printf("[%2d] - %s\n", sn, pszPath);
if (map_env.find(sn) == map_env.end())
{
pszTmp = new char[strlen(pszPath) + 1];
strcpy(pszTmp, pszPath);
map_env.insert(std::pair<int, const char*>(sn, pszTmp));
}
else {
assert(false);
}
}
else {
// 有环境变量
if (ReplaceEnv(pszPath, pszTmp, lenTmp))
{
// printf("[%2d] - %s\n", sn, pszPath);
if (map_env.find(sn) == map_env.end())
{
map_env.insert(std::pair<int, const char*>(sn, pszTmp));
}
else {
assert(false);
}
}
else {
printf("[%2d] - error : %s\n", sn, pszPath);
}
}
b_rc = true;
} while (false);
assert(true == b_rc);
return b_rc;
}
bool ReplaceEnv(const char* pszSrc, char*& pszDst, int& lenDst)
{
bool b_rc = false;
const char* pszCur = NULL;
int iPosDst = 0;
bool bFindEnvBegin = false;
bool bFindEnvEnd = false;
char szEnv[_MAX_PATH];
int iPosEnv = 0;
char* pszEnvValue = NULL;
pszDst = NULL;
lenDst = 0;
do {
if ((NULL == pszSrc) || (strlen(pszSrc) <= 0))
{
break;
}
pszDst = new char[_MAX_PATH];
lenDst = _MAX_PATH;
pszCur = pszSrc;
while (0x00 != pszCur[0])
{
if (!bFindEnvBegin)
{
if (pszCur[0] != '%')
{
pszDst[iPosDst++] = pszCur[0];
}
else {
bFindEnvBegin = true;
memset(szEnv, 0, sizeof(szEnv));
pszCur++;
continue;
}
}
else if (bFindEnvBegin && !bFindEnvEnd)
{
if (pszCur[0] != '%')
{
szEnv[iPosEnv++] = pszCur[0];
}
else {
bFindEnvEnd = true;
// get %szEnv% value pEnv
pszEnvValue = getenv(szEnv);
if (NULL == pszEnvValue)
{
goto END;
}
// append pEnv to pszDst
strcpy(pszDst, szEnv);
}
}
pszCur++;
}
b_rc = true;
} while (false);
END:
if (!b_rc)
{
if (NULL != pszDst)
{
delete[] pszDst;
pszDst = NULL;
}
lenDst = 0;
}
return b_rc;
}