2013-03-18 1 views
1

О пакетном скриптинге, борясь с %~dp0. Проблема заключается в том, что в некоторых частях моего сценария %~dp0 возвращает то, что он должен вернуть, то есть полный путь с диском в папке, содержащей запущенный скрипт (здесь: 'C: \ Data \ name \ App \ App \ '). В некоторых других частях кода %~dp0 возвращает только диск, содержащий скрипт (здесь: 'C: \').% ~ dp0 не возвращает папку, содержащую сценарий запуска

Вот мой сценарий (первая партия сценарий когда-либо: D):

@ECHO OFF 

ECHO. 
:: run the script with the command new-built.bat /all -arch x86 -config release 


SETLOCAL EnableDelayedExpansion 
SET options=arch version config 
SET what_to_build=all lib 
:: the three following lines returns what is expected 
echo %%~dp0 is returning : %~dp0 
echo %%~p0 is returning : %~p0 
echo %%~d0 is returning : %~d0 
echo The absolute path to this script is : %~dp0%0 

:: read what to build, ie all or lib only 
FOR %%i in (%what_to_build%) do if %1==/%%i (
SHIFT 
GOTO %%i 
) 


::the following sections (:readoptions and :optlp) work together to collect the options entered in the command, used to launch this script. It saves the values the two arrays "options" and "what_to_build" array 

:readoptions 
echo Entered the read options label 
rem -- initialises variables arch, version and config with empty string 
FOR %%i IN (%options% badoptions) DO (SET %%i=) 
:optlp 
echo Entered the read options loop 
SET _parm1=%1 
IF NOT DEFINED _parm1 GOTO :END 
IF DEFINED _parm1 FOR %%i IN (%options%) DO IF .%_parm1%==.-%%i SET %%i=%2 
IF DEFINED %%i shift&shift&(SET _parm1=) 
IF DEFINED _parm1 SET badoptions=%badoptions% %1&SHIFT 
GOTO :optlp 

:all 
echo Entered the all label ... 
CALL :readoptions %* 
echo About to build complete app for x86 in release config 
set CYGWIN_DIR="%~dp0" 
:: I want this line to return "C:\Data\name\App\App\" without quotes, but it's returning "C:\" 
echo Cygwin dir (not returning what I want): %CYGWIN_DIR% 
rem build lib 
call %~dp0\build_scripts\build_lib_x86.bat 
rem build the Visual Studio Solution 
start "Build App x86 - release config" /W "%~dp0%build_scripts\build_app_x86_release.bat" 


goto :end 

:END 
echo Program is done 
endlocal 

Вот след я получаю:

%~dp0 is returning : C:\Data\name\App\App\ 
%~p0 is returning : \Data\name\App\App\ 
%~d0 is returning : C: 
The absolute path to this script is : C:\Data\name\App\App\new-build.bat 
Entered the all label ... 
Entered the read options label 
Entered the read options loop 
Entered the read options loop 
Entered the read options loop 
Entered the read options loop 
Entered the read options loop 
Entered the read options loop 
Program is done 
About to build complete app for x86 in release config 
Cygwin dir (not returning what I want) : "C:\" 
The system cannot find the path specified. 
Program is done 

Там должно быть что-то происходит, что мне не хватает. Любая помощь будет высоко оценен.

+2

Зачем вам не удалять путь в начале с помощью 'set basepath =% ~ dp0' и использовать% basepath% в вашей: all label – rene

+3

Перемещение' SHIFT'% 1 в% 0, теряя был в% 0 ... но если вы используете 'SHIFT/1', он должен оставить% 0 (и, следовательно,% ~ dp0) незатронутым. –

ответ

1

Ooooh - Big troublez!

@ECHO OFF 

ECHO. 
:: run the script with the command new-built.bat /all -arch x86 -config release 


SETLOCAL EnableDelayedExpansion 
SET options=arch version config 
SET what_to_build=all lib 
:: the three following lines returns what is expected 
echo %%~dp0 is returning : %~dp0 
echo %%~p0 is returning : %~p0 
echo %%~d0 is returning : %~d0 
echo The absolute path to this script is : %~dp0%0 

Учитывая нового built.bat/все -arch x86 -config релиз затем %1 является /all

:: read what to build, ie all or lib only 
FOR %%i in (%what_to_build%) do if %1==/%%i (
SHIFT 
GOTO %%i 
) 

SO, поскольку %1 является /all, это прибудет в :all с %1=-arch %2=x86 %3=-config %4=release НО %*=/all -arch x86 -config release

HAD %1 был /lib, а затем, но придет на :lib

НО для любого другого значения% 1, обработка будет просто зарядить прямо через здесь к следующему оператору ....


... так что мы приходим к :all с %1=-arch %2=x86 %3=-config %4=release НО %*=/all -arch x86 -config release

:all 
echo Entered the all label ... 
CALL :readoptions %* 

с: readoptions вызывается с %* каждый из оригинальных параметров передается: readoptions но вместо goto :EOF вы изменили это «Гото END and hence the message Программы осуществляется is displayed - and processing returns to the statement following the CALL`

echo About to build complete app for x86 in release config 
set CYGWIN_DIR="%~dp0" 
:: I want this line to return "C:\Data\name\App\App\" without quotes, but it's returning "C:\" 
echo Cygwin dir (not returning what I want): %CYGWIN_DIR% 
rem build lib 
call %~dp0\build_scripts\build_lib_x86.bat 
rem build the Visual Studio Solution 
start "Build App x86 - release config" /W "%~dp0%build_scripts\build_app_x86_release.bat" 


Давайте начнем заново ...

Я считаю, что вы на самом деле хотите CYGWIN_DIR быть присвоено значение имя вашего каталога CYGWIN. Вероятно, мы могли бы это исправить, но гораздо лучше, если он постоянно установлен в вашей среде. Самый простой способ сделать это:

SETX CYGWIN_DIR "wherever your cygwin dir is" 
SETX CYGWIN_DIR "wherever your cygwin dir is" /M 

(первый присваивает значение для экземпляров NEW CMD в текущем сеансе LOGON, второй для будущих сеансов входа в систему IOW, выполните второй и перезагрузки ....Вы можете удалить запись, если вы хотите с помощью Setx CYGWIN_DIR «» )

@ECHO OFF 
ECHO. 
:: run the script with the command new-built.bat /all -arch x86 -config release 

SETLOCAL EnableDelayedExpansion 
SET options=arch version config 
SET SLASHOPTS=ALL LIB 
(SET SWITCHES=) 
:: %CD% is the magic pseudovariable for the current directory. 
:: quote it if you wish 
SET CYGWIN_DIR=%CD% 
:: The above line of course only if you want CYGWIN_DIR to be set to the current directory 
CALL :READOPTIONS %* 
:: NOTE THAT %badoptions% now contains a list of the items NOT 
:: involved in the OPTIONS, SWITCHES or SLASHOPTIONS 
:: read what to build, ie all or lib only 
:: ONE WAY... 
IF DEFINED ALL goto ALL 
IF DEFINED LIB goto LIB 
:: ANOTHER WAY to do the same thing 
for %%i in (%SLASHOPTS%) DO if defined %%i goto %%i 
:: EEK! Neither ALL not LIB was specified - what to do? 
echo EEK! Neither ALL not LIB was specified - exiting! 
goto :EOF 


:all 
echo Entered the all label ... 
echo About to build complete app for x86 in release config 
echo Cygwin dir (not returning what I want): %CYGWIN_DIR% 
rem build lib 
:: I'll assume %CYGWIN_DIR%\build_scripts is where you're keeping this batch 
call %CYGWIN_DIR%\build_scripts\build_lib_x86.bat 
rem build the Visual Studio Solution 
start "Build App x86 - release config" /W "%CYGWIN_DIR%\build_scripts\build_app_x86_release.bat" 


goto end 

:LIB 
echo LIB processing not yet defined 
goto end 

:END 
echo Program is done 
endlocal 

:readoptions 
echo Entered the read options label 
rem -- initialises variables arch, version and config with empty string 
:readoptions 
FOR %%i IN (%options% %slashopts% %switches% badoptions) DO (SET %%i=) 
:optlp 
SET _parm1=%1 
IF NOT DEFINED _parm1 GOTO :EOF 
FOR %%i IN (%switches%) DO IF /i %_parm1%==-%%i SET %%i=Y&(SET _parm1=) 
IF NOT DEFINED _parm1 shift&GOTO :optlp 
FOR %%i IN (%slashopts%) DO IF /i %_parm1%==/%%i SET %%i=Y&(SET _parm1=) 
IF NOT DEFINED _parm1 shift&GOTO :optlp 
FOR %%i IN (%options%) DO IF /i %_parm1%==-%%i (
SET %%i=%2 
IF DEFINED %%i shift&shift&(SET _parm1=) 
) 
IF DEFINED _parm1 SET badoptions=%badoptions% %1&SHIFT 
GOTO :optlp 

Обратите внимание, что я немного измененную: readoptions, так что вы можете установить -option anoptionvalue или -switch или /slashoption

Заметим также, что вы может передать участок от: readoptions до конца к самостоятельному пакетный файл, скажем readoptions.bat и место, что файл в любом месте на вашем path (см set path из командной строки), а затем ANY партия может выполнить

CALL READOPTIONS %* 

читать ваши варианты/переключатели/slashoptions как вы индивидуально определены их в переменных options, switches и slashopts в вашей партии - и badoptions будет содержать все оставшиеся параметры ...

(Примечание по двоеточием: call: обычный список параметров вызывает внутреннюю процедуру с «приватными» параметрами parameterlist список параметров подпрограммы вызовов вызывает процедуру EXTERNAL с «приватными» параметрами parameterlist; то есть. кнопку [партии] файл «рутина from somewhere on the path`

goto :eof 

Является встроенный объект, чтобы перейти к физическому файлу истекшим. Это завершает CALL и возвращается к строке после ИЛИ полностью завершает пакет. )

+0

Большое спасибо за ваш очень точный ответ, а также за советы. Вопрос: Мне нужно написать только один скрипт. Следовательно, могу ли я использовать 'set' для переменной, или мне нужно сделать их переменной окружения с помощью' setx'? – Myna

+1

В частности, для переменной 'CYGWIN_DIR' вам нужно выполнить команды' SETX' 'ONCE', чтобы вы вводили их непосредственно в приглашении. Другой способ сделать это: «Настройки> Панель управления> Система> Дополнительные параметры системы> Переменные среды», а затем добавить новую переменную. Поскольку это записывает значение в реестр, вам необходимо перезагрузить компьютер, но как только это будет сделано, оно будет зафиксировано, и 'CYGWIN_DIR' будет автоматически установлен на значение, которое вы дали ему для всех будущих сеансов. Вы можете видеть, какие значения назначаются с помощью 'SET' из приглашения, кроме динамических' псевдовиделей ', таких как 'RANDOM', описанных в' SET /? ' – Magoo

 Смежные вопросы

  • Нет связанных вопросов^_^