我一直在阅读如何avoid spaghetti code in batch files。
在意大利面代码的例子中,我意识到我登录时使用的批处理文件几乎适合这个例子。有人可以帮我把我的批处理文件没有意大利面条代码吗?
@ECHO OFF
CLS
:MENU
echo Welcome %USERNAME%
echo 1 - Start KeePass
echo 2 - Backup
echo 3 - FireFox
echo 4 - Exit
SET /P M=Please Enter Selection, then Press Enter:
IF %M%==1 GOTO StarKeePass
IF %M%==2 GOTO Backup
IF %M%==3 GOTO FireFox
IF %M%==4 GOTO :EOF
GOTO MENU
:StarKeePass
SET keePass="%USERPROFILE%\KeePass\KeePass-2.30\KeePass.exe"
SET kdb="%USERPROFILE%\KeePass\PasswordDatabase\PasswordDatabase.kdbx"
echo I'll start KeePass for You
START "" %keePass% %kdb%
GOTO MENU
:Backup
SET backup="%USERPROFILE%\backup.bat"
call %backup%
GOTO MENU
:FireFox
cd "C:\Program Files (x86)\Mozilla Firefox\"
start firefox.exe
GOTO MENU
答案 0 :(得分:2)
在这种情况下,如果你想使用子程序,你应该这样做:
@ECHO OFF
CLS
:MENU
echo Welcome %USERNAME%
echo 1 - Start KeePass
echo 2 - Backup
echo 3 - FireFox
echo 4 - Exit
SET /P M=Please Enter Selection, then Press Enter:
IF %M%==1 CALL :StartKeePass
IF %M%==2 CALL :Backup
IF %M%==3 CALL :FireFox
IF %M%==4 GOTO :EOF
GOTO MENU
:StartKeePass
SET "keePass=%USERPROFILE%\KeePass\KeePass-2.30\KeePass.exe"
SET "kdb=%USERPROFILE%\KeePass\PasswordDatabase\PasswordDatabase.kdbx"
echo I'll start KeePass for You
START "" %keePass% %kdb%
GOTO :EOF
:Backup
SET "backup=%USERPROFILE%\backup.bat"
call %backup%
GOTO :EOF
:FireFox
cd "C:\Program Files (x86)\Mozilla Firefox\"
start firefox.exe
GOTO :EOF
请注意,我改变了一些事情。您应该使用call :label
goto :eof
/ exit /b
而不是转到...转到菜单。除此之外,你有一个拼写错误Star t KeePass,而不是set variable="value"
,使用set "variable=value"
会更好。这也会接受值中的空格,但不会为变量添加引号
下次您应该将此帖子发布到code review,因为这些事情并非真正的错误
答案 1 :(得分:0)
如果您想完全删除goto
,只需再次调用脚本即可继续使用它。此外,如果您使用的是Windows之后的Windows版本,请查看choice命令,因为它无需检查用户是否输入了无效输入。
@echo off
cls
echo Welcome %USERNAME%
echo 1 - Start KeePass
echo 2 - Backup
echo 3 - FireFox
echo 4 - Exit
choice /C:1234 /M "Please enter your selection: " /N
:: The first option listed by choice's /C option will return an errorlevel value of 1, the second 2, and so on
if %errorlevel% equ 1 (
SET keePass="%USERPROFILE%\KeePass\KeePass-2.30\KeePass.exe"
SET kdb="%USERPROFILE%\KeePass\PasswordDatabase\PasswordDatabase.kdbx"
echo I'll start KeePass for You
START "" %keePass% %kdb%
)
:: I've converted these to one-liners simply for personal preference.
:: You can keep these the way you had them if you put them inside of parentheses like with option 1.
if %errorlevel% equ 2 call "%USERPROFILE%\backup.bat"
if %errorlevel% equ 3 start "" "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
if %errorlevel% equ 4 exit /b
:: Calls this script again, simulating a goto :MENU
:: Personally, I'd stick with a label and a goto in this instance,
:: but this is how you could do it if you don't want to use goto at all
call %0
如果用户可以做出的每个选择都相当简单(即它可以简化为一个或两个命令),您可能希望以这种方式编码;否则,肯定会使用Dennis建议的子程序。
答案 2 :(得分:0)
我对此进行组织,添加了对m
变量的重置,允许处理一些意外输入,并在一个代码块中对其进行全部检查。
Dennis van Gils'没有错。回答,想通知我会给你一个不同的方法。
@echo off
setlocal enableDelayedExpansion
:menu
set "m="
cls
echo/Welcome !username!
echo/
echo/1 - Start keepass
echo/2 - Backup
echo/3 - Firefox
echo/4 - Exit
echo/
set /p "m=Please enter selection, then press enter:"
if not defined m (
cls
echo/Error: Empty input.
pause
) else (
if "!m!" equ "1" (
set "keepass=!userprofile!\keepass\keepass-2.30\keepass.exe"
set "kdb=!userprofile!\keepass\passworddatabase\passworddatabase.kdbx"
echo/I'll start keepass for you
start "" !keepass! !kdb!
) else (
if "!m!" equ "2" (
set "backup=!userprofile!\backup.bat"
call !backup!
) else (
if "!m!" equ "3" (
cd "c:\program files (x86)\mozilla firefox\"
start firefox.exe
) else (
if "!m!" equ "4" (
goto :eof
) else (
cls
echo/Error: ["!m!"] not recognized.
pause
)
)
)
)
)
goto :menu
注意:echo/
被用作习惯,echo:
和echo\
我误认为文件路径/网址的某些部分,echo.
是如此精心注意到的它的命令时间更长。
另外,我更喜欢!
优于%
以及setlocal enableDelayedExpansion
纯粹偏好,以及简单的块编码。