Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Программа, показывающая, какой файл выполнится, если набрать ком. переданную в парам. (http://forum.oszone.net/showthread.php?t=245413)

элькхар 24-10-2012 21:08 2011525

Программа, показывающая, какой файл выполнится, если набрать ком. переданную в парам.
 
Написать программу, показывающую, какой файл выполнится, если набрать команду, переданную в параметрах.

Должны поддерживаться как команды с расширением, так и без (т.е. calc и calc.exe)

Пример запуска:
>which.cmd calc
C:\Windows\system32\calc.exe

//Желательно без использования сложных регулярных выражений.

Iska 24-10-2012 21:36 2011538

Код:

@echo off
setlocal enableextensions enabledelayedexpansion

set sCommand=%~1

if defined sCommand (
        if "%~x1" equ "" (
                call :CheckExtension "%sCommand%" %pathext%
        ) else (
                for %%i in ("%sCommand%") do if exist "%%~$PATH:i" echo "%%~$PATH:i"
        )
) else (
        echo Usage: %~nx0 ^<command^>
        exit /b 1
)

endlocal
exit /b 0

:CheckExtension
        setlocal enableextensions enabledelayedexpansion
       
:Repeat
        set sExtension=%~2
       
        if defined sExtension (
                for %%i in ("%~1%sExtension%") do if exist "%%~$PATH:i" echo "%%~$PATH:i"
                shift /2
                goto :Repeat
        )
       
        endlocal
        exit /b 0


элькхар 24-10-2012 23:19 2011607

Огромное спасибо не расскажите как это работает?
1)
Код:

enableextensions
что делает этот параметр?
2)
Код:

if "%~x1" equ ""
что значит equ ? просмотрел справку по ифу не нашел
3)
Код:

call :CheckExtension "%sCommand%" %pathext%
зачем нужна данная строка? и что значит
Код:

"%sCommand%" %pathext%
4)
Код:

"%%~dp$PATH:i%%~i"
зачем тут %%~i
5)
Код:

echo Usage: %~nx0 ^<command^>
Usage?? и %~nx0 ^<command^>
6)
Код:

set sExtension=%~2
~2 означает что берется все начиная с третьего символа, или я путаю?
7)
Код:

if defined sExtension
если она не пустая?

8)и по всему репиту немогу точно понять что он делает ~1,~2 и ~i ставят меня в тупик

Iska 25-10-2012 02:41 2011690

1.
Код:

setlocal /?
2. «Если первый параметр командного файла имеет расширение, то …». Подробности:
Код:

call /?
Цитата:

Цитата элькхар
что значит equ ? просмотрел справку по ифу не нашел »

Стало быть, у Вас Windows XP. Там в справке по «if /?» есть ошибка — написано «eql» вместо «equ». Означает — «equal», «равно». Можете почитать в chm-справке:
Код:

hh.exe mk:@MSITStore:C:\WINDOWS\Help\ntcmds.chm::/if.htm
3. «Вызвать новый контекст командного файла по метке «:CheckExtension», передав ему в качестве параметров переменные окружения «sCommand» и «pathext».

4.
Цитата:

Цитата элькхар
зачем тут %%~i »

Добавить к найденному пути («%%~dp$PATH:i%») имя самого файла.

Я тут просто «перебдел» c «dp». Можно упростить: «%%~dp$PATH:i%%~i» → «%%~$PATH:i». Я поправил код выше.

5. Можно так:
Код:

echo Использование: %~nx0 ^<команда^>
Это просто подсказка, вызываемая в случае, если командный файл был вызван без параметра.

6. Путаете. «Присвоить переменной окружения «sExtension» значение второго переданного на метку параметра».

7 и 8.
Цитата:

Цитата элькхар
если она не пустая? »

«Если переменная окружения «sExtension» существует».

Смотрите:
читать дальше »
мы вызываем процедуру (это, конечно, никакая не процедура, но так проще для разговора) «:CheckExtension» и передаём ей несколько параметров:
Код:

call :CheckExtension "%sCommand%" %pathext%
Что в неё приходит? Например, мы вызвали пакетный файл с параметром «notepad». Значит, в процедуру приходит первый параметр — имя файла «notepad» и содержимое переменной окружения «%pathext%», обычно это:
Код:

.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;
Следовательно, вторым параметром будет передан «.COM», третьим —«.EXE» и т.д. (дело в том, что точка с запятой — «;» — рассматривается командным процессором как разделитель, такой же как и пробел).


Рассмотрим ход исполнения:
Код:


:Repeat
        set sExtension=%~2
       
        if defined sExtension (
                for %%i in ("%~1%sExtension%") do if exist "%%~$PATH:i" echo "%%~$PATH:i"
                shift /2
                goto :Repeat
        )

по шагам.

На первом шаге
читать дальше »
переменная окружения «sExtension» принимает значение «.COM». Далее успешно проверяется, существует ли она. Затем, выполняется:
Код:

                for %%i in ("%~1%sExtension%") do if exist "%%~$PATH:i" echo "%%~$PATH:i"
или, если подставить значения:
Код:

                for %%i in ("notepad.COM") do if exist "%%~$PATH:i" echo "%%~$PATH:i"
что означает: проверить существование «notepad.COM» в путях, перечисленных в переменной окружения PATH и, если такой файл существует — вывести полный путь к нему. Поскольку файла «notepad.COM» в путях не будет найдено, ничего не будет выведено. Следующей командой — «shift /2» параметры процедуры:
Код:

"notepad" .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;
будут «сдвинуты» таким образом:
Код:

"notepad" .EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;
Затем произойдёт переход к метке «:Repeat».


На втором шаге
читать дальше »
переменная окружения «sExtension» принимает значение «.EXE». Далее снова успешно проверяется, существует ли она. Затем, снова выполняется:
Код:

                for %%i in ("%~1%sExtension%") do if exist "%%~$PATH:i" echo "%%~$PATH:i"
или, если подставить значения:
Код:

                for %%i in ("notepad.EXE") do if exist "%%~$PATH:i" echo "%%~$PATH:i"
— проверить существование «notepad.EXE» в путях, перечисленных в переменной окружения PATH и, если такой файл существует — вывести полный путь к нему. Поскольку файл «notepad.EXE» будет найден в пути «C:\WINDOWS\system32\», будет выведено: «"C:\WINDOWS\system32\notepad.exe"». Затем снова командой — «shift /2» уже текущие параметры процедуры:
Код:

"notepad" .EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;
будут «сдвинуты» ещё «левее»:
Код:

"notepad" .BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;
Затем снова произойдёт переход к метке «:Repeat».


И так до тех пор, пока
читать дальше »
у нас после очередного исполнения «shift /2» параметры с:
Код:

"notepad" .WSH;
не примут вид:
Код:

"notepad"
Тогда на очередном шаге исполнения, после команды:
Код:

set sExtension=%~2
переменная окружения «sExtension» будет удалена (поскольку в этот момент второго параметра уже нет, не существует, остался только первый параметр «"notepad"»). Следовательно, условие в следующей команде «if defined sExtension …» окажется ложным и произойдёт выход из процедуры и возврат в контекст основного пакетного файла.


В принципе, можно предусмотреть условие, которое сразу будет прерывать последующий перебор расширений, как только будет найдено первое же совпадение.


Время: 16:24.

Время: 16:24.
© OSzone.net 2001-