Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is there a way to do "if defined %1"

1,937 views
Skip to first unread message

Cyberclops

unread,
Dec 16, 2009, 1:08:19 AM12/16/09
to
For normal environment variables

if defined <variable>

works just fine.

This is not true for command line variables.

if defined %1

and

if defined 1

do not have the desired result.

if "%1"==""

is not safe if %1 has poison characters in it.

The only way I have found to do it is

set ENV=%1
if defined ENV

but this mucks with the environment so to be safe you have to
"setlocal/endlocal" it.

Am I missing someother trick?

Thanks,

Cyberclops

foxidrive

unread,
Dec 16, 2009, 1:32:57 AM12/16/09
to
On Tue, 15 Dec 2009 22:08:19 -0800 (PST), Cyberclops <lowell...@gmail.com> wrote:

> if "%1"==""
>
>is not safe if %1 has poison characters in it.

This works preety well

if "%~1"==""

Frank P. Westlake

unread,
Dec 16, 2009, 11:01:40 AM12/16/09
to
"Cyberclops"
news:50805b8f-4bfe-4509...@q16g2000vbc.googlegroups.com...

> if "%1"==""

The suggestion already given is good.


> set ENV=%1
> if defined ENV
>
> but this mucks with the environment so to be safe you have to
> "setlocal/endlocal" it.

True and false. Assuming you intended to do something like this:

If DEFINED %1 (
REM Use %1.
)

Then instead of SETLOCAL you could

Set "ENV=%~1"
If DEFINED ENV (
REM Use ENV.
Set "ENV="
)


> Am I missing someother trick?

We all are.

Here is another option:

Echo.%1|FindStr .&& Echo DEFINED

Frank


Frank P. Westlake

unread,
Dec 17, 2009, 11:54:48 AM12/17/09
to
From e-mail:

> As far as you idea
>
> set "ENV=%~1"
> if DEFINED ENV (
> REM Use ENV.
> set "ENV="
> )
>
> This is only advisable if you know the ENV is not already
> defined.
> That is what the setlocal/endlocal is needed.

You are correct.

If "ENV" already exists in the environment then the statement 'SET
"ENV=%~1"' would undefine it if "%1" EQU "". So the test works as
intended but it looses any previous value of ENV. This could be a
problem if your script is running in an environment that is common to
other processes and the variable you choose for the test ("ENV" in this
example) is important in one of those other processes. To avoid this
problem SETLOCAL should be used as you stated.

Frank


dtcomput...@gmail.com

unread,
Feb 20, 2016, 8:02:31 PM2/20/16
to
I realize this is an older thread but for any future folks that look at this, the following worked fine for me.

@cls
@SET PARAMONE=%1
@SET PARAMTWO=%2

@if not defined PARAMONE (SET PARAMONE=No parameter one defined)
@if not defined PARAMTWO (SET PARAMTWO=No parameter two defined)

@echo %PARAMONE%
@echo %PARAMTWO%


I tried this after reading what Cyberclops said that he tried but was worried about mucking with the environment.
I'm using Windows 7 x64

JJ

unread,
Feb 21, 2016, 2:47:21 AM2/21/16
to
Batch parameter variables including the variable used for the FOR command,
are not named variables, so they can't be referenced like environment
variables.

Compare this with the pseudo variables such as %TIME%, %ERRORLEVEL%,
%RANDOM%, etc. They're not environment variables but are named variables, so
they can be checked with the DEFINED operator.

Pedro M

unread,
Feb 21, 2016, 11:04:10 AM2/21/16
to
If you want to know if %1 is defined, then this:

if NOT "%~1"==""
...is what you want, meaning if the %1 parameter isn't empty, it's because it's defined.
Writing it without the NOT as I've seen here is just making the condition if %1 is not defined ("" being an empty value), which is the opposite of what you want.

you can also opt for this:
if NOT [%~1]==[]
but careful with the spaces of %1

pro...@berkeley.edu

unread,
Feb 21, 2016, 2:01:10 PM2/21/16
to
I decided to interpret the question literally. Following is screen capture
from Win7Pro.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C:\Users\JoeUser>set first=

C:\Users\JoeUser>\cmd\demo\IsMyArgDefined first

The value of argument %1 is "first".

But since "first" itself is not the name of a variable
containing a value, "%1" is NOT defined.

C:\Users\JoeUser>set last=99999

C:\Users\JoeUser>\cmd\demo\IsMyArgDefined last

The value of argument %1 is "last".

And because "last" has a VALUE of "99999",
we must acknowledge that "%1" IS defined.

C:\Users\JoeUser>\cmd\demo\IsMyArgDefined username

The value of argument %1 is "username".

And because "username" has a VALUE of "JoeUser",
we must acknowledge that "%1" IS defined.

C:\Users\JoeUser>rlist \cmd\demo\IsMyArgDefined.cmd
=====begin C:\cmd\demo\IsMyArgDefined.cmd ====================
01. @echo off
02. setlocal enableextensions enabledelayedexpansion
03. set my1=%1
04. echo/
05. echo/The value of argument %%1 is "%my1%".
06. echo/
07. if defined %my1% (
08. echo/And because "%my1%" has a VALUE of "!%my1%!",
09. echo/we must acknowledge that "%%1" IS defined.
10. ) else (
11. echo/But since "%1" itself is not the name of a variable
12. echo/containing a value, "%%1" is NOT defined.
13. )
14. goto :EOF
=====end C:\cmd\demo\IsMyArgDefined.cmd ====================
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

So is the question really 'does %1 have a value?' or is it 'does the value of
%1 have a value'?

--
Phil Robyn

Sponge Belly

unread,
Feb 25, 2016, 6:44:51 PM2/25/16
to
Hi Cyberclops!

Sorry for the late reply. :) This little nugget catches everything
except CRs (suppressed by cmd) and LFs (notoriously difficult to trap
when embedded in command line parameters):

@echo off & setlocal enableextensions disabledelayedexpansion
set "param1=%~1"
for %%^" in ("") ^
do if not defined param1 set %%~"param1=%1%%~"
set param1
endlocal & goto :eof

A doff of the hat to Jeb for the "disappearing quotes" technique
explained at: http://stackoverflow.com/a/4645113

HTH!

- SB

pro...@berkeley.edu

unread,
Feb 26, 2016, 9:48:06 PM2/26/16
to
C:\Users\JoeUser>showme \cmd\demo\IfDefinedParm1.cmd
≡≡≡≡≡begin C:\Cmd\demo\IfDefinedParm1.cmd≡≡≡≡≡
1. @echo off & setlocal enableextensions disabledelayedexpansion
2. set "param1=%~1"
3. for %%^" in ("") ^
4. do if not defined param1 set %%~"param1=%1%%~"
5. set param1
6. endlocal & goto :eof
≡≡≡≡≡end C:\Cmd\demo\IfDefinedParm1.cmd≡≡≡≡≡


C:\Users\JoeUser>\cmd\demo\IfDefinedParm1 '" end'
param1='" end'

C:\Users\JoeUser>\cmd\demo\IfDefinedParm1 ' " end'
param1='

Desired result is
param1=' " end'

--
Phil Robyn

petu...@googlemail.com

unread,
Feb 27, 2016, 12:19:41 PM2/27/16
to
Phil, you will note that the intent is to return the first parameter which it does correctly.
By including the space between the single and double quotes you've inadvertently created a second parameter.

pro...@berkeley.edu

unread,
Feb 27, 2016, 1:32:33 PM2/27/16
to
On Saturday, February 27, 2016 at 9:19:41 AM UTC-8, petu...@googlemail.com wrote:
> Phil, you will note that the intent is to return the first parameter which it does correctly.
> By including the space between the single and double quotes you've inadvertently created a second parameter.

No, it was on purpose. Look at these two examples:

>IfDefinedParm1 'abc" end '
param1='abc" end '

>IfDefinedParm1 'abc end '
param1='abc

So which one of these two is 'wrong'? In my view, the first one is handled
correctly, the second one, incorrectly. A space should just be another
character, and that's how it's treated in the first example. But in an
inadvertent way.

petu...@googlemail.com

unread,
Feb 27, 2016, 1:58:43 PM2/27/16
to
I take the opposing view Phil, your first example is outputting the wrong data.

pro...@berkeley.edu

unread,
Feb 29, 2016, 7:31:06 PM2/29/16
to
On Saturday, February 27, 2016 at 10:58:43 AM UTC-8, petu...@googlemail.com wrote:
> I take the opposing view Phil, your first example is outputting the wrong data.

'Wrong' as in 'not what you expected'?

When I saw the first result, I got my hopes up that it was going to be able to
handle both single and double quotes as delimiter characters. But no such luck.

Here's a comparison:

File=(No Filename defined)

····.····1····.····2····.····3····.····4····.····5····.····6····.····
0001.
0002. CutTheCake change 'each "X" and every "Y" and "Z"' to
0003. "every single X, Y, and Z" in "set U = s e f u l " 12
0004. in current/last-1 nolist
0005.
0006. parm1={change}
0007. parm2={each "X" and every "Y" and "Z"}
0008. parm3={to}
0009. parm4={every single X, Y, and Z}
0010. parm5={in}
0011. parm6={set U = s e f u l }
0012. parm7={12}
0013. parm8={in}
0014. parm9={current/last-1}
0015. parm10={nolist}
0016.
0017.
0018. \cmd\demo\ifdefinedparm1 'each "X" and every "Y" and "Z"'
0019. in "set U = s e f u l " 12 nolist
0020.
0021. param1='each

See how CutTheCake is able to handle different delimiter characters?

See how the 'ifdefinedparm1' method is not able to do this?

If you are getting input for a 'change' command, it all boils down to
change OLD to NEW in some context or other. In this example, OLD is
parm2 and NEW is parm4. It's just taking the whole task of dealing with
user input to a new level.

--
Phil Robyn
0 new messages