Parameter values passed into a CommandBox command don't have to be static. Any part of the parameter which is enclosed in backticks (`) will be evaluated as a CommandBox expression. That means that the enclosed text will be first executed as though it were a separate command and the output will be substituted in its place.
Any valid command can be used as an expression, including calls to native OS binaries, CFML functions, or REPL one-liners. Note that any text that a command immediately flushes to the console during its execution (like a download progress bar) will not be returned by the expression, though it will display on the console.
Take for instance, this simple command that prints out the contents of a file:
It can be used as a dynamic parameter like so:
In the example above, the contents of the defaultServer.txt
file will be passed in as the value of the "name" parameter to the "server start" command. If the contents of the file was the text myServer
, the equivalent final command would be:
There can be more than one expression in a single parameter value. Expressions can also be combined with static text and they will all be evaluated in the order they appear:
That would output something similar to:
If you need to use an actual backtick in a parameter value, escape it with a backslash.
Which outputs
This unlocks a new world of scripting potential when combined with other abilities like native OS binary execution and CFML functions from the CLI. Here's some examples to get your gears turning:
Set a package property in box.json
equal to the current date passed through a CFML date mask
Set properties based on manipulations of previous values:
Perform CFML operations on local files:
Execute environment-aware install scripts based on local files. (isProduction.txt
would contain the text true
or false
in this ex.)
The CommandBox interactive shell already allows for a command to pipe data into another Command.
Since CommandBox commands don't have a "standard input", the output of the previous command is passed into the second command as its first parameter. In this instance, the grep
command's first parameter is called input
so it receives the value returned by the cat
command. The "find me"
text becomes the second parameter-- in this case, expression
.
There is nothing special about a parameter that can received piped input. In fact, any command can receive piped input for its first parameter. The following commands all accomplish the same thing.
This allows you to get creative by combining commands together like so:
This takes a package name and replaces some text on output. One benefit is that Windows users don't have a native sed
command in their OS, but those commands inside a CommandBox Recipe will execute consistently on any machine.
What if you aren't using the interactive shell and you want to pipe into CommandBox from your OS's native shell? This is also supported, and as long as there is a command specified, the piped input will become the first parameter as before.
If you pipe text directly into the box executable with no command specified in the parameters, each line of your piped text will be read from the standard input as a command.
If a value is a single word with no special characters, you don't need to escape anything. Certain characters are reserved as special characters though for parameters since they demarcate the beginning and end of the actual parameter and you'll need to escape them properly. These rules apply the same to named and positional parameters.
If a parameter has any white space in it, you'll need to wrap the value in single or double quotes. It doesn't matter which kind you use and it can vary from one parameter to another as long as they match properly.
Quotes are actually allowed unescaped in a value, so long as they don't appear at the start of the string.
However, if the parameter contains white space and is surrounded by quotes, you'll need to escape them with a backslash.
Hint Only like quotes need to be escaped. Single quotes can exist inside of double and vice versa without issue. These examples below are perfectly valid.
Backticks are used in parameter values to demarcate an expression to be parsed. Escape them with a backslash. All backticks need escaped regardless of whether they are encased on single or double quotes.
If you have an equals sign in your value, you'll need to escape it with a backslash unless you've quoted the entire string.
Line breaks can't be escaped directly as of Commandbox 4.0. Instead, most terminals let you enter a carriage return by pressing Ctrl-V and pressing enter. To enter a line feed, press Ctrl-V followed by Ctrl-J.
On ConEMU, which performs a paste operation with Ctrl-V, use Ctrl-Shift-V instead.
A tab character can't be escaped directly as of CommandBox 4.0. Instead, most terminals let you enter a tab char by pressing Ctrl-V followed by tab. In ConEMU which allows pasting via Ctrl-V, you can use Ctrl-Shift-V and then press tab.
Since the backslash is used as our escape character you'll need to escape any legitimate backslash that happens to precede a single quote, double quote, equals sign, or letter n.
This will print foo\=bar
Many Commands accept a path to a folder or file on your hard drive. You can specify a fully qualified path that starts at your drive root, or a relative path that starts in your current working directory. To find your current working directory, use the pwd
command (Print Working Directory). To change your current working directory, use the cd
command.
Here are examples of fully qualified paths in Windows and *nix-based:
Info Note that if you start a path with a single leading slash in Windows, it will be an absolute path using the drive letter of the current working directory.
For a relative path, do not begin with a slash.
File system paths will be canonicalized automatically which means the following is also valid:
If you are on Windows, CommandBox supports UNC server shares bu accessing the name of the server or the IP address. Note, you can use forward or backslashes in Windows, but a UNC path MUST start with two backslashes.
Backslashes need to be escaped from the command line and in JSON, so most usage of UNC server paths will require you to type four slashes like \\\\
which will properly escape to \\
You cannot directly list the contents of a server like \\webdev01
as that is not a true directory. You always need to access a specific share like \\webdev01/webroot
.
By default, CommandBox will access UNC paths using the same permissions of the user that the box
process was started with. There's no way to specify a user, so if you need to use a custom user, you'll need to run native NET USE
command from the CLI first to change how it is authenticating. Unfortunately, this is a limitation of how Java accesses UNC paths so CommandBox has little control over it.
When a command has an argument with a type of Globber
for a file path, that means you can use file globbing patterns to affect more than one file at a time. Globbing patterns are common in Bash as well as places like your .gitignore
file. They use common wildcard patterns to provide a partial path that can match zero or hundreds of files all at the same time.
If a globbing pattern contains a question mark, that will match any single character. So a pattern of ca?.txt
would match car.txt
, and cat.txt
, but not cart.txt
. You can use a wildcard more than once. p?p?.cf?
would match files named papa.cfm
and pipe.cfc
.
If a globbing pattern contains a single asterisks, that will match zero or more characters inside a filename or folder name. So d*o
matches doodoo
, dao
, and just do
. The wildcard only counts inside a file or folder name, so models/*.cfc
will only match cfc files in the root of the models folder.
To extend the previous example, if we did models/**.cfc
that would match any cfc file in any subdirectory, no matter how deep.
Here's some examples of what file globbing might look like:
Here's some more examples of how the wildcards work
Since the Globber library can handle more than one globbing pattern, any command that uses a Globber type can accept a comma-delimited list of patterns. The following will list any .cfm AND .md files in the directory.
Many commands accept parameters to control how they function. Parameters are entered on the same line as the command and separated by a space and can be provided as named OR positional, similar to how CFML functions can be called. You cannot mix named and positional parameters in the same command though or an error will be thrown. There is also a concept of "flag" for boolean parameters that can be combined with named or positional parameters for brevity and readability.
Named parameters can be specified in any order and follow the format name=value
. Multiple named parameters are separated by a space.
Positional parameters omit the name=
part and only use the value. They must be supplied in the order shown in the or help command. We try to place the most common parameters at the beginning so you can use named parameters easily. Here is the equivalent of the named command above:
Of course, only the required parameters must be specified. I'm only including all of them here for the completeness of the example.
If you do not provide a parameter that is required for the command execution, the shell will stop and ask you for each of the missing parameters before the command will execute.
Info It is not necessary to escape special characters in parameter values that are collected in this manner since the shell doesn't need to parse them. The exact value you enter is used.
In addition to quoting parameter values, parameter names can also be quoted. This is useful when setting keys into settings or JSON files that have spaces, hyphens or special characters. Each of these examples are supported:
Each of those examples will create this in your box.json
Any parameter that is a boolean type can be specified as a flag in the format --name
. Flags can be mixed with named or positional parameters and can appear anywhere in the list. Putting the flag in the parameter list sets that parameter to true. This can be very handy if you want to use positional parameters on a command with a large amount of optional parameters, but you don't want to specify all the in-between ones.
You can also negate a flag by putting an exclamation point or the word "no" before the name in the format --no{paramName}
. This sets the parameter to false which can be handy to turn off features that default to true.