Skip to content.

Scott Arciszewski

Software, Privacy, Security, Innovation

Writing Command Line Utilities in Various Programming Languages

August 2, 2014 4:04 PM • Development, PHP, Migrated, Tutorial

This was originally posted on a website I was developing over a year ago called Keenotes.


A command line utility is a program that can be passed commands and parameters (input) from the command line to achieve an effect and may result in output that can be useful (either by itself or in conjunciton with other command line tools). Command line utilities are usually written for advanced computer users (system administrators, security professionals, or just plain old hackers), although they're actually much simpler than user-friendly software. This makes the command line interface ideal for an intermediate programmer to begin experimenting with.

Command Line Utilities (in General)

Command line utilities are programs that are accessed through a Command Line Interface (CLI), usually Command Prompt or a Linux shell (sh, bash, csh, zsh, etc), and generally has the following workflow:

  1. Process the information supplied by the user.
  2. Decide what features to use based on step 1.
  3. Process the data.
  4. Optionally, output something to "stdin" (usually the CLI screen)

For example, if you open Command Prompt on Windows or the Terminal and Linux and type this command in, your computer will send 6 packets to google.com and report its travel time (unless you're on a network that blocks ICMP traffic, like UCF):

ping -n 6 google.com
  • ping: Run the ping program. Usually located in /bin/ping or C:\Windows\System32\PING.EXE
  • -n: The next flag is the number of echo requests to send to the host
  • 6: We should send six of them
  • google.com: This is the host we should send echo requests to

So now that we're familiar with what a command line utility is, it's time to start making them.

Command Line Utilities in C

C is kind of an obvious starting place for command line utilities, since most of them are written in C. If you've taken a typical C class, you might set up your program to look something like this:

#include "stdio.h"
#include "stdlib.h"
int main() {
  printf("Hello, world!\n");
  return 0;
}

Before you do anything else, you should change line 4 of your program to accept two arguments: an integer named argc, and a pointer to an array of characters called argv. Like so:

#include "stdio.h"
#include "stdlib.h"
int main(int argc, char* argv[]) {
  printf("Hello, world!\n");
  return 0;
}

When you compile and execute your program, you will now be able to pass arguments to main from the command line. But the code as written doesn't currently do anything with them. Let's change that.

#include "stdio.h"
#include "stdlib.h"
int main(int argc, char* argv[]) {
  int i = 0;
  printf("\nArguments passed to this utility:\n");
  for(i = 0; i < argc; i++) {
    printf("\t%s\n", argv[i]);
  }
  return 0;
}

Compile this program, and run it like the ping command above. It should list every argument passed, including the path and name of executable.

This is what happened: Your operating system counted the number of arguments you provided, and stored this number in argc. Then, each argument was a string in the array argv.

Then, the meat of our code just iterated through the user-supplied arguments and printed them to the console.

From this point on, what you do with the program is up to your creativity and requirements. So let's take a look at a couple other languages to see some of their peculiarities.

Command Line Utilities in Perl

Perl has been called "the duct tape of the internet" because of its flexibility and usefulness, especially in writing scripts for the command line. Perl offers a less mainstaking way to access arguments passed to Perl scripts (although if you want, $ARGV and $ARGC are still offered):

#!/usr/bin/perl
use warnings;
use strict;
my $firstParameter = shift || 'defaultValue1'; #$ARGV[0]
my $secondParameter = shift || 'default2'; #$ARGV[1]
my $thirdParameter = shift || 'see the pattern?'; #$ARGV[2]
##
# Do stuff here...
##

shift is a Perl expression that takes the first value off an array and shortens it. Luckily for us, it will automatically use ARGV outside of the scope of a subroutine.

Command Line Utilities in PHP

PHP is a little quirky. Consider the following program. Note that $argv and $argc are provided by PHP just like with Perl (only they're lowercase):

<?
echo "\nArguments passed:\n";
for($i = 0; $i < $argc; $i++) {
    echo "\t{$argv[$i]}\n";
}
?>

In order to run this program, the command you will have to run is:

php /path/to/cli.php param param2 param3

You might expect the output to look something like this:

Arguments passed:
          php
          /path/to/cli.php
          param
          param2
          param3

But instead, it actually looks like this:

Arguments passed:
          /path/to/cli.php
          param
          param2
          param3

PHP's $argv and $argc ignore the path of the PHP interpreter, and instead $argv[0] is the absolute filename of the PHP script that's being executed. I suspect this is the case with other languages as well (such as command-line Java).

A Functional Example - Pseudorandom Bytes (PHP)

Since you've made it this far, here's a command line utility I wrote for Linux in PHP that reads random bytes through PHP's openssl_random_pseudo_bytes() to produce a pseudorandom character string. It accepts two arguments: The number of bytes to produce, and the total keyspace (for example, abcdefghijklmnopqrstuvwxyz for all letters, 0123456789 for all numbers) of the desired output.

<?php
function convBase($numberInput, $fromBaseInput, $toBaseInput) {
// FROM PHP.NET        [email protected]
// Modified by Scott Arciszewski    [email protected]
$noPeriods = false;
if((strpos($fromBaseInput, '.') === false) && (strpos($toBaseInput, '.') === false)) {
  $noPeriods = true;
}
if ($fromBaseInput==$toBaseInput) return $numberInput;
  $fromBase = str_split($fromBaseInput,1);
  $toBase = str_split($toBaseInput,1);
  $number = str_split($numberInput,1);
  $fromLen=strlen($fromBaseInput);
  $toLen=strlen($toBaseInput);
  $numberLen=strlen($numberInput);
  $retval='';
  if($toBaseInput == '0123456789') {
    $retval=0;
    for($i = 1; $i <= $numberLen; $i++) {
      $retval = bcadd($retval,
                  bcmul(array_search($number[$i-1], $fromBase), bcpow($fromLen,$numberLen-$i))
                );
    }
    if($noPeriods) return preg_replace('/\..*?/', '', $retval); #Everything after the period
    return $retval;
  }
  if($fromBaseInput != '0123456789') {
    $base10 = convBase($numberInput, $fromBaseInput, '0123456789');
  }
  else {
    $base10 = $numberInput;
  }
  if ($base10 < strlen($toBaseInput)) {
    return $toBase[$base10];
  }
  while($base10 != '0')
  {
    $retval = $toBase[bcmod($base10,$toLen)].$retval;
    $base10 = bcdiv($base10,$toLen,0);
  }
  if(is_float($retval)) return intval($retval);
  return $retval;
}
if($argc < 2) {
  echo "\nUsage: php randomBytes.php [length] [keyspace]\n";
  echo "\tLength is the number of bytes\n";
  echo "\tKeyspace is every character in the keyspace.\n";
  echo "\tExample, generate a 16-digit number:\n";
  echo "\t\tphp randomBytes.php 16 0123456789\n";
  echo "\tThe default keyspace is all printable ASCII characters.\n";
  die("\n"); // Exit
}
if(!is_numeric($argv[1])) die("Length must be a number!");
$length = ceil($argv[1]); // Always round up
if($argc < 3) {
  $keyspc = '!"#$%^\'()+,-./0123456789:;<=>[email protected][\\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
  // Default: all 94 printable ASCII characters
} else {
  $keyspc = $argv[2];
}
$entropy = openssl_random_pseudo_bytes($length); // A generous overestimate
echo substr(convBase(bin2hex($entropy), '0123456789abcdef', $keyspc), 1, $length);
exit;

To use this feature, you would do something like this:

php randomBytes.php 36 abcdefghijkmnopqrstuvwxyz >> /home/user/passwordlist.txt
    echo >> /home/user/passwordlist.txt

This would append 36 letters to /home/user/password.txt and then a newline, so you can create a list of random alphabetical passwords to use at a later date.

Screenshot demonstrating the code in action

I hope this article shed some light on writing command line programs and look forward to seeing what you can create with this newfound knowledge.

Blog Archives Categories Latest Comments

Want to hire Scott Arciszewski as a technology consultant? Need help securing your applications? Need help with secure data encryption in PHP?

Contact Paragon Initiative Enterprises and request Scott be assigned to your project.