Syntax examples
Refer to this page for examples of command syntax recognized by brash.
Refer to this page for examples of string expressions.
Commands, Functions, and Scripts
When questions of the form: "How do you do XYZ in brash?" come up, the
the short answer is usually: "just like you do it in GNU bash."
Most programming questions, like
- how to define functions?
- how to read files?
- how to manipulate strings?
- how to write loops
- how to prompt the user for input?
- how to set the command line prompt?
in brash, are explained in the online GNU bash manuals. Use to google find what you are looking for. Or, not finding it there,
use the brash "builtins" command or the -h option to the builtins to find it.
Though brash is not a duplicte of GNU bash. One obvious exception is that brash currently doesn't support string arrays or maps.
The built in commands generally follow the brash naming conventions and command line options. However, the simulation
is not perfect. All of the brash builtin commands interpret -h and --help to give you a help message that describes
their use.
Click here for a list of differences
There are more builtin commands in brash than in bash. Use the command "builtins" to get a detailed list.
Brash reads ~/.brashrc not ~/.bashrc. ~ will be the same as $HOME which will be the same as $USERPROFILE.
Linux Versus Windows Scripting
These paragraphs discuss how linux and windows scripting in brash/bash works differently.
File Name Differences
Sadly, in the beginning, Microsoft chose to emulate the VAX operating system, not the Unix operating system and
thus file names on windows are quite different than on Unix and now Linux.
This means that no matter how much brash emulates the bourne shell, you just won't be able run scripts written for the
unix environment in the windows world. CYGWIN tries to let you do that, but then you get stuck with the bizarre situation
where the CYGWIN tools all understand the unix directory tree, but if you write your own C/C++ visual studio program then you have to re-invent
the linux emulation.
After struggling with this for some years, I decided just to make brash be a plain-vanilla windows application, not a simulation of unix
that is running on Windows. But like many Windows apps, it is tolerant of unix file names -- except the special ones.
Yes it is annoying to have to duplicate your \'s whenver you are defining file names -unless they are enclosed in apostrophes. But the tab
completion function of the console reduces the confusion somewhat when you are at the command line. The it duplicates them for you if you
forget, and it lets you write forward slash, and tab completion will turn them into \\.
Brash is case insensitive with respect to file names. So is its tab completion function. Everything else about it is case sensitive though.
Command Line Option Differences
And yes, Microsoft does confuse the definition of command line options by using / instead of - as the command line option
identifier character. But in practice, this does not cause much trouble. When invoking a command, you just have to know
which character to use.
Scripting Examples
These sections walk through some example scripts and talk about how they work. This is not a programming
class -- as there are plenty of the GNU bash and bourne shell training sites on the net. The following
topics address how brash is and is not like the bourne shell. In the process some fairly complex
program examples are included.
Drive Letters -- an example sameness and difference between GNU bas and brash
In linux/unix there are no drive letters, but this is an important concept in Windows. The "cd" command in brash
changes both the current drive and the current directory, so to a brash script, their are no "drives", only pathnames
that get you to the other drives.
The windows "cd" command has an option, /D, that makes it work like that too.
However, if you enjoy typing "e:" to get to drive E, here's a script that will
- find all your drives
- automatically create script language functions named x: or whatever as appropriate
letter functions for you.
You can put it in your $USERPROFILE\\.brashrc (or ~/.brashrc).
to make it an automatic part of your brash environment when you start the interpreter.
#
# The following code creates functions which will take you to the top
# level directory on other drives.
#
# These functions are named: c:, p:, q:, s:, etc
#
# Note that the built-in drives don't show up in net use, so for
# drive c:, or a:, or your optical drives, you probably need to
# manually create a function. See c:() below
#
c:() { pushd c:/ ; } # a function for drive C:
#
# create a string which, when evaluated, will define functions for
# all the drives that have been found by "net use"
#
net use |
.regex -m '[A-Z]:' |
while read status local rest
do
# fix up missing status
case "$status" in
*:)
# status was empty
# slide the other fields over 1
# and put unknown in the status
rest="$local $rest"
local="$status"
status="unknown"
;;
esac
case "$status" in
OK)
echo "${local,,}() { echo pushd $local ; pushd $local/; }"
;;
esac
done | read -f cmd
#
# variable cmd now contains the text of all the needed function definitions.
#
# evaluate that string as a sequence of commands.
#
eval "$cmd"
unset cmd
Note the use of a mixture of sophisticated scripting features from both bash and brash in the above:
- comments (# ....)
- function definitions ( c:() { ... } )
- external program invocation (net use)
- constructing commands as strings and executing them. (eval)
- piping
- case statements
- while loops
- sophisticated string manipulation (${local,,})
- .regex is a brash builtin that has key parts of grep and sed built into it.
It is being used to discard all lines of output from "net use" that don't contain
strings that look like drive letters.
- "read -f" is a brash specific version lets you read a whole file into a string.
The file being read, in this case, is the output of the while loop. It is being
concatenated into a string by this operation.
But if you check the -h output from the read command in brash, you will see that its command
line options are quite different from the rest of brash read's functionality. The normal
parts of the same, but the sophisticated parts are different. In particular, note how the
read command splits lines of text, produced by net use, into words and then only picks out
a few of those words as interesting enough to store in separate variables.
Note: This script highlights a signficant difference in the way that brash works and the
way that the bourne and brash shells work. In brash, the final stage of a pipe
is executed in the current shell environment -- whereas in bash and the bourne
shell, the final state of a pipe is executed in discarded sub shell.
This brash behavior allows for variables in the current shell to be populated by
the read command -- but is a difference of importance to script writers.
In bash and the bourne shell, you would write something like this:
cmd=$(
net use | grep -e '[A-Z]:' |
while read status local rest
do
...
done
)
eval "$cmd"
unset cmd
The .regex command is vaguely like grep -- when used with the -m option. See also -h for
more details about how .regex also emulates sed.
Also note that in this example, forwardslash, not backslash is used in pathnames. If you
wanted to write the above code using backslashes, all the examples would have to be done
with two backslashes, not one.