6
\$\begingroup\$

Recently I am working on batch to make a very simple command line interface.

The code looks like this:

@echo off
echo Simple command-line interface
echo.
:input.get
set /p input="COMMAND\>"
set input5=%input:~0,5%
if "%input%"=="something" goto something
if "%input5%"=="echo " goto echo

:echo
set content=%input:~5%
echo.%content%
goto input.get

:something
::do something
goto input.get

Is this really a good way to do it? I have posted a question about "How to check whether labels exist" in stack overflow, but if i input "echo hi" then it will be nearly impossible to check the tag.

Is it good to use both ways? (check whether label exist -> if not exist -> do "if" check)

\$\endgroup\$
  • \$\begingroup\$ I'd change 'if "%input5%"=="echo " goto echo' to 'if not "%input5%"=="echo " goto input.err', and create an input.err subroutine that prompts the user to try again. What you have will lead to an unhelpful echo that doesn't let them know they did anything wrong. \$\endgroup\$ – John Deters Feb 7 '14 at 6:06
  • \$\begingroup\$ if it is an infinite loop then the users cannot go back to main menu, and that will be a HUGE problem. restarting costs tile, right? \$\endgroup\$ – Jamie Feb 9 '14 at 9:52
  • \$\begingroup\$ A quick thing I would really do is change comments from :: to REM . :: was used for ending labels a while ago, but are no longer used for that. Using REM is much more acceptible. Hope I helped. \$\endgroup\$ – mgthomas99 Dec 21 '14 at 16:20
4
\$\begingroup\$

You can use a FOR /F to parse out the command from the arguments.

I would define a variable containing a delimited list of all valid commands. Then you can use simple search and replace to validate whether the user entered command is valid.

Addition of a new command is as easy as adding the command to the list, and creating a labeled subroutine for the new command.

I would use CALL instead of GOTO so that each routine can easily parse the arguments. The only disadvantage is CALL will double up quoted carets ("^" becomes "^^")

Here is a basic framework that can easily be extended. Note that user entered ! will be corrupted (or expanded) because of delayed expansion. There are simple ways to get around this limitation with additional code.

@echo off
setlocal enableDelayedExpansion
echo Simple command-line interface
echo(

:: Define all valid commands: make sure there is a space between each command
:: and also one at beginning and end
set "commands= something echo exit "

:input.get

:: Clear the existing value in case user hits <Enter> without entering anything
set "input="

:: Get the next command
set /p "input=COMMAND\>"

:: Parse command into command and arguments.
for /f "tokens=1* delims= " %%A in ("!input!") do (

  REM check if command is valid (not case sensitive) and act accordingly
  if "!commands: %%A =!" equ "!commands!" (
    echo Invalid command: %%A
  ) else if /i %%A equ exit (
    exit /b
  ) else (
    call :%%A %%B
  )
)
echo(
goto input.get


:something
echo Doing something with Arg1=[%1] and Arg2=[%2]
exit /b

:echo
echo(%*
exit /b
\$\endgroup\$
  • \$\begingroup\$ I think it is good, however, i don't know NEARLY EVERYTHING about for /f. I know for /l,for. \$\endgroup\$ – Jamie Feb 13 '14 at 11:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.