2008 Winter Scripting Games

Tip of the Week: Retrieving Command-Line Arguments

Tip of the Week Comic

*
On This Page
Retrieving Command-Line ArgumentsRetrieving Command-Line Arguments
Retrieving Command-Line Arguments in VBScriptRetrieving Command-Line Arguments in VBScript
Retrieving Command-Line Arguments in Windows PowerShellRetrieving Command-Line Arguments in Windows PowerShell
Retrieving Command-Line Arguments in PerlRetrieving Command-Line Arguments in Perl

Retrieving Command-Line Arguments

According to the old saying there are only two sure things in life: death and taxes. Well, now you have to add a third item to this list: you can bet your bottom dollar that, at some point in the 2008 Winter Scripting Games, you’ll be required to write a script that can read in a command-line argument.

And yes, that goes for beginners as well as for the more experienced scripters.

But that’s OK; as you’re about to see, reading command-line arguments is actually one of the easiest things you’ll be asked to do during the Scripting Games.

Note. You say you don’t even know what command-line arguments are? Then you should take a peek at this section of the Microsoft Windows 2000 Scripting Guide.

Top of pageTop of page

Retrieving Command-Line Arguments in VBScript

If you want to get picky, the truth is that you can’t read command-line arguments using VBScript; that’s because VBScript doesn’t know anything about command-line arguments. But that’s all right; after all, VBScript doesn’t have to know anything about command-line arguments. That’s because Windows Script Host takes care of all that stuff.

Any time you supply a command-line argument to a script that runs under Windows Script Host (that includes JScript scripts as well as VBScript scripts) those arguments are automatically stored in the Wscript.Arguments collection. Want to echo back the value of the first command-line argument supplied to a script? Then all you have to do is echo back the value of the first item in the Arguments collection:

Wscript.Echo Wscript.Arguments(0)

Ah, good question: if we’re echoing back the value of the first argument then why did we refer to Wscript.Arguments(0)? Shouldn’t we have said Wscript.Arguments(1) instead?

Well, maybe we should have, but it’s a good thing we didn’t; had we done so the script likely would have failed. (Or at the very least, not echoed back the value of the first command-line argument.) Why? Well, in most scripting languages, items assigned to an array or a collection are automatically assigned index numbers. Most of these arrays and collections are zero-based: that means that the first item in the array is given an index number of 0; the second item in the array is given an index number of 1; and so. If we tried to echo back the value of the item with the index number 1 (meaning the second item in the Arguments collection) one of two things would have happened:

The script would have failed with a “Subscript out of range error.” That would occur if we only supplied one command-line argument when starting the script.

The script would have echoed back the value of the second command-line argument (assuming we started the script using multiple command-line arguments.) In that case the script wouldn’t fail, but it also wouldn’t give us what we wanted: the value of the first command-line argument.

See how that works? Suppose you want to echo back the value of the third argument supplied to a script. Then you need to use code like this:

Wscript.Echo Wscript.Arguments(2)

Like it or not (and we know that some people don’t like it), that’s just the way things work.

If you want to echo back the values of all the command-line arguments supplied to a script you can use code similar to this:

For Each strArgument in Wscript.Arguments
    Wscript.Echo strArgument
Next

All we’ve done here is set up a For Each loop that loops through all the values in the Wscript.Arguments collection. When we first enter the loop the value of the initial command-line argument is assigned to the loop variable strArgument; we then simply echo back the value of strArgument. What happens the second time through the loop? You got it: the value of the second command-line argument is assigned to the loop variable strArgument and we again echo back the value of strArgument. If we start our script using the command cscript C:\Scripts\Test.vbs red yellow blue green we should get the following output:

red
yellow
blue
green

Pretty darn simple, if we do say so ourselves.

If you’d like to see an example of a script that actually does something with a command-line argument, well, consider this two-line chunk of code:

Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.DeleteFile Wscript.Arguments(0)

What we’re doing here is creating an instance of the Scripting.FileSystemObject object, then using the DeleteFile method to delete the file whose file path was supplied as the script’s first command-line argument. Want to get rid of the file C:\Temp\Tempfile.txt? Then just start the script using a command similar to this:

cscript c:\scripts\test.vbs c:\temp\tempfile.txt

Note. Needless to say, the preceding command assumes you’ve saved the two-line sample script as C:\Scripts\Test.vbs.

Top of pageTop of page

Retrieving Command-Line Arguments in Windows PowerShell

In Windows PowerShell, command-line arguments are automatically stored in a variable named $args. Does that make it easy to get at a particular command-line argument? You bet it does; for example, this code echoes back the value of the first command-line argument supplied to a script:

$args[0]

See? We weren’t kidding when we told you this was easy. Want to echo back the value of the second command-line argument supplied to the script? Okey-doke:

$args[1]

Etc., etc.

OK, now what if we want to echo back all the command-line arguments supplied to a script? Well, this one line of code should do the trick:

$args

This is even easier than we thought; that’s because PowerShell can display all the values stored in an array without requiring you to set up a For loop.

If you’re looking for a more practical example of using command-line arguments in a PowerShell script, well, look no further. The following script uses the Remove-Item cmdlet to delete any file whose file path is supplied as a command-line argument:

Remove-Item $args[0]

That’s all there is to it.

Top of pageTop of page

Retrieving Command-Line Arguments in Perl

Reading command-line arguments in Perl isn’t very hard; however, it can be just a tiny bit tricky. Why? Well, by default, Perl stores all its command-line arguments in an array named @ARGV. If you’re new to Perl, but experienced in either VBScript or PowerShell, that might lead you to believe that you can echo back the value of the first command-line argument by using code like this:

print @ARGV[0];

That makes sense. Unfortunately, though, it doesn’t work.

In Perl, the @ sign is used to denote an array. However, when you try to access individual items in that array you don’t use the array name (e.g., @ARGV). Instead, you need to use a “scalar” version of the array. What does that mean? That essentially means that you replace the @ sign with the $ sign, like so:

print $ARGV[0];

Believe it or not, that line of code will return the first command-line argument supplied to the script. (As with both VBScript and PowerShell, the first item in an array has an index number of 0.) Want to echo back the value of the second argument supplied to the script? Well, the second item in an array has the index number 1, which means you’d use this code:

print $ARGV[1];

And so on.

Interestingly enough, if you want to loop through all the command-line arguments then you do need to use @ARGV. This code echoes back all the command-line arguments supplied to a script:

foreach $strArgument (@ARGV)
    {print "$strArgument\n";}

As you can see, what we’ve done here is set up a foreach loop that loops through all the values in the @ARGV array. Note the syntax of the foreach loop: after the foreach statement we indicate the loop variable ($strArgument) followed by the array we want to loop through (@ARGV). Note, too that @ARGV is enclosed is parentheses. After that, and enclosed in curly braces, we have the code we want to run each time through the loop; in this case, we simply use the print function to echo back the argument and a carriage return-linefeed (\n).

So how could we use a command-line argument in a script? Well, here’s a simple little script that deletes the file supplied as a command-line argument:

unlink $ARGV[0];

Start the script using a command line perl C:\Scripts\Test.pl C:\Temp\Tempfile.txt and see what happens. (Hint: C:\Temp\Tempfile.txt should disappear.)


Top of pageTop of page