Running Scripts and Components
▪ One-shot execution of .cfs, .cfm, .cfc ▪ Examples per file type.
Executing Commands and Scripts with LuCLI
Welcome! This guide shows you how to run one-shot commands and scripts directly from the command line.
Overview
LuCLI gives you multiple ways to execute code and commands straight from the command line:
- CFML Scripts - Execute
.cfm,.cfs, and.cfmlfiles - CFML Components - Execute
.cfcfiles - Module Commands - Run LuCLI modules with full syntax or shortcuts
- LuCLI Scripts - Execute
.luclibatch scripts
All of these execution modes support helpful global flags:
--verbose/-v- See what's happening behind the scenes--debug/-d- Get detailed debug output when things go wrong--timing/-t- See exactly where time is being spent
1. Executing CFML Scripts
One of the simplest ways to use LuCLI is running CFML scripts directly - just point it at your file and go!
Supported File Types
.cfs- CFML script files (fully supported with ARGS array).cfm- CFML template files.cfml- CFML files (alternative extension)
Basic Syntax
lucli <script-file> [arguments...]
Examples
Simple script execution
lucli hello.cfs
With arguments
lucli process-data.cfs input.txt output.txt
With flags and arguments
lucli --verbose script.cfs arg1 arg2
lucli --debug --timing process.cfm "argument with spaces"
Accessing Arguments in Scripts
For .cfs files
Good news - LuCLI automatically sets up an ARGS array for you with:
ARGS[1]- The script filenameARGS[2]- First argument (if provided)ARGS[3]- Second argument (if provided)- etc.
Example script (hello.cfs):
writeOutput("Hello from CFML script!" & chr(10));
if (structKeyExists(variables, "ARGS") && isArray(ARGS)) {
writeOutput("Arguments passed: " & arrayLen(ARGS) & chr(10));
for (i = 1; i <= arrayLen(ARGS); i++) {
writeOutput(" Arg " & i & ": " & ARGS[i] & chr(10));
}
}
Run it:
lucli hello.cfs foo bar baz
Output:
Hello from CFML script!
Arguments passed: 4
Arg 1: hello.cfs
Arg 2: foo
Arg 3: bar
Arg 4: baz
For .cfm and .cfc files
Arguments are available through the built-in __arguments variable:
<cfif structKeyExists(variables, "__arguments") and isArray(__arguments)>
<cfloop from="1" to="#arrayLen(__arguments)#" index="i">
<cfoutput>Arg #i#: #__arguments[i]#<br></cfoutput>
</cfloop>
</cfif>
Built-in Variables
LuCLI provides several handy variables automatically in your scripts:
__cwd- Current working directory__scriptFile- Script filename__scriptPath- Absolute path to script__scriptDir- Directory containing the script__arguments- Array of arguments passed to script__argumentCount- Number of arguments__env- System environment variables__systemProps- Java system properties__lucliHome- LuCLI home directory path
Example usage:
writeOutput("Script: " & __scriptFile & chr(10));
writeOutput("Location: " & __scriptDir & chr(10));
writeOutput("Working Dir: " & __cwd & chr(10));
writeOutput("Arguments: " & __argumentCount & chr(10));
2. Executing CFML Components
You can also run CFC (ColdFusion Component) files directly - great for creating reusable command-line tools!
Basic Syntax
lucli <component-file> [arguments...]
Examples
# Execute a component
lucli MyComponent.cfc
# With arguments
lucli MyComponent.cfc arg1 arg2
# With flags
lucli --verbose --debug MyComponent.cfc param1 param2
Component Structure
For direct execution, structure your component with a main function - here's a simple example:
component {
public void function main() {
// Component logic here
writeOutput("Component executed!" & chr(10));
// Access arguments
if (structKeyExists(variables, "__arguments")) {
for (var arg in __arguments) {
writeOutput("Argument: " & arg & chr(10));
}
}
}
}
4. LuCLI Batch Scripts (.lucli files)
Want to automate multiple commands? LuCLI scripts let you create batch files that run commands sequentially - perfect for deployment, testing, or any repetitive task!
File Extension
Use the .lucli extension for batch scripts.
Basic Syntax
lucli <script-file.lucli>
Script Format
Each line in a .lucli file is executed as a separate LuCLI command:
#!/usr/bin/env lucli
# Example LuCLI batch script
# Comments start with #
echo "Starting automated tasks..."
# Run modules
hello-world
modules list
# Execute CFML scripts
process-data.cfs input.txt output.txt
# Run server commands
server status
echo "Tasks complete!"
Making Scripts Executable
Here's a neat trick - you can make .lucli scripts run directly without typing lucli first:
Step 1: Add a shebang line
Add this as the first line of your script:
#!/usr/bin/env lucli
Step 2: Make the file executable
chmod +x script.lucli
Step 3: Run directly
./script.lucli
Complete Example
Create a file called deploy.lucli:
#!/usr/bin/env lucli
# Deployment automation script
echo "Starting deployment process..."
# Run tests
cfformat --check *.cfs
test-runner
# Start server
server start --name production --port 8080
# Deploy application
deploy-app production
echo "Deployment complete!"
server status
Make it executable and run:
chmod +x deploy.lucli
./deploy.lucli
Or run directly:
lucli deploy.lucli
Script Features
- Comments: Use
#for comments (just like shell scripts) - Command execution: Each line runs as if you typed it yourself
- Error handling: The script keeps going even if one command fails
- Sequential execution: Commands run in order, top to bottom
- No interactive prompts: Scripts run non-interactively, so they won't pause for input
Flags with LuCLI Scripts
You can pass global flags when executing .lucli scripts:
lucli --verbose script.lucli
lucli --debug --timing deploy.lucli
These flags apply to the script execution environment.
Command Precedence
When you run lucli something, LuCLI determines what to execute using this precedence:
- Known subcommands -
server,modules,terminal,cfml,help - LuCLI scripts - Existing
.luclifiles - CFML files - Existing
.cfs,.cfm, or.cfcfiles - Module shortcuts - Modules in
~/.lucli/modules/ - Error - Show help if nothing matches
Example Decision Flow
lucli server # → Recognized subcommand, shows server help
lucli hello.cfs # → Existing file, executes as CFML script
lucli deploy.lucli # → Existing file, executes as LuCLI batch script
lucli hello-world # → No file found, tries module shortcut
lucli unknown # → Nothing found, shows error and available options
Error Handling
File Not Found
$ lucli nonexistent.cfs
Error: File not found: nonexistent.cfs
Invalid File Type
$ lucli document.pdf
Error: 'document.pdf' is not a CFML file (.cfm, .cfc, or .cfs)
Module Not Found
$ lucli unknown-module
Error: Module 'unknown-module' not found
Available modules:
- hello-world
- cfformat
- test-runner
Script Execution Error
$ lucli broken.cfs
Error executing CFML script 'broken.cfs': Invalid CFML syntax at line 5
Use --debug flag to see detailed stack traces:
lucli --debug broken.cfs
Performance Considerations
Engine Initialization
Here's something to keep in mind: the Lucee engine needs to start up each time you run a command (takes about 1-2 seconds). Once it's running, everything else is fast!
To get the best performance:
- Batch operations - Use
.lucliscripts to batch multiple commands - Module development - Modules stay within one engine instance
- Server mode - For web applications, use
lucli server startinstead of one-shot execution - Timing analysis - Use
--timingflag to identify bottlenecks
Timing Example
$ lucli --timing process.cfs data.txt
⏱️ Timing Results:
Lucee Engine Initialization: 891ms
Script Preparation: 12ms
Script Execution: 145ms
CFML File Execution: 1,048ms
Best Practices
Here are some tips we've learned from building and using LuCLI:
1. Use appropriate file types
.cfsfor pure CFML script (best choice for command-line tools).cfmfor templates with mixed CFML/HTML.cfcfor reusable components
2. Handle arguments properly
It's always a good idea to check if arguments exist before using them:
if (structKeyExists(variables, "ARGS") && isArray(ARGS) && arrayLen(ARGS) > 1) {
inputFile = ARGS[2]; // First actual argument (ARGS[1] is script name)
} else {
writeOutput("Usage: script.cfs <input-file>" & chr(10));
// In a real script, you'd exit here
}
3. Provide usage information
Your future self (and others) will thank you for including helpful usage text:
if (__argumentCount == 0) {
writeOutput("Usage: process.cfs <input> <output>" & chr(10));
writeOutput(" input - Input file path" & chr(10));
writeOutput(" output - Output file path" & chr(10));
return;
}
4. Use built-in variables
Leverage LuCLI's built-in variables for file paths:
// Use __scriptDir for relative file paths
dataFile = __scriptDir & "/data/input.json";
// Use __cwd for current working directory
outputFile = __cwd & "/results.txt";
5. Create modules for reusable code
Running the same script over and over? Time to make it a module!
lucli modules init my-utility
# Edit ~/.lucli/modules/my-utility/Module.cfc
lucli my-utility arg1 arg2
6. Use .lucli scripts for automation
Multi-step workflows? .lucli scripts are your friend:
# build.lucli
cfformat *.cfs
run-tests
package-app
deploy-to-staging
Exit Codes
LuCLI follows standard Unix exit code conventions:
- 0 - Success! Everything worked
- 1 - General error (file not found, execution error, etc.)
- 2 - Invalid command or arguments
You can check these in your shell scripts:
if lucli process.cfs input.txt; then
echo "Processing succeeded"
else
echo "Processing failed"
fi
Additional Resources
- Module Development - See module documentation for creating your own modules
- Help System - Use
lucli --helpandlucli <command> --helpfor built-in help - Examples - Check
~/.lucli/modules/for module examples after runninglucli modules list - Server Mode - See server documentation for web application development
Summary Quick Reference
# CFML Scripts
lucli script.cfs arg1 arg2
lucli template.cfm param1 param2
# CFML Components
lucli Component.cfc arg1 arg2
# Module Commands (full syntax)
lucli modules run module-name args...
# Module Shortcuts
lucli module-name args...
# LuCLI Batch Scripts
lucli script.lucli
chmod +x script.lucli && ./script.lucli
# With Global Flags
lucli --verbose --debug --timing script.cfs