HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Making a .bat batch command-line interface

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
linebatchinterfacecommandmakingbat

Problem

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)

Solution

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 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

Context

StackExchange Code Review Q#41121, answer score: 4

Revisions (0)

No revisions yet.