ChELL supports three distinct execution modes for maximum flexibility:
-
Interactive Mode - Traditional REPL shell
-
Command Mode (
-c) - Execute single or multiple commands and exit -
Script Mode (
-f) - Run script files with full automation support
Key Features:
-
Semicolon support - Run multiple commands sequentially in a single invocation
-
Script files - Create reusable .chell scripts with shebang support
-
Error handling - Choose between continue-on-error (default) or stop-on-error (
-e) -
Auto-detection - Automatically recognize script files vs connection targets
-
Session persistence - CWD and context maintained across commands
Standard REPL mode with full command history, tab completion, and prompt.
Invocation:
chell # Start interactive shell
chell user@cube.url # Connect and start interactive shellUse cases: - Manual exploration and debugging - Ad-hoc data analysis - Learning ChRIS commands
Execute one or more commands non-interactively and exit immediately. Perfect for automation, scripts, and CI/CD pipelines.
Syntax:
chell -c "<command>"Examples:
# Single command
chell -c "ls /PIPELINES"
# With connection
chell -c "ls /home" user@cube.example.org
# Complex command
chell -c "cat /PIPELINES/analysis/pipeline.yml"Run multiple commands sequentially in the same session. Commands share the same connection, authentication, and working directory.
Syntax:
chell -c "command1; command2; command3"Examples:
# Basic sequence
chell -c "pwd; ls /home; pwd"
# Change directory persists
chell -c "cd /PIPELINES/user; ls; cat analysis.yml"
# DICOM workflow
chell -c "cd /SERVICES/PACS/patient123; ls *.dcm; cat study_001.dcm | dcmdump -"
# File operations
chell -c "mkdir /home/user/results; cd /home/user/results; touch output.txt"Semicolons inside quotes are preserved, not treated as separators.
Examples:
# Semicolon in string is preserved
chell -c "echo 'Line1;Line2'; pwd"
# Output:
# Line1;Line2
# /home/user
# Mixed quotes
chell -c "echo \"hello;world\"; ls; echo 'foo;bar'"Traditional approach (slow):
chell -c "cd /PIPELINES" # 2-3s connection/auth
chell -c "ls" # 2-3s connection/auth
chell -c "cat pipeline.yml" # 2-3s connection/auth
# Total: 6-9 secondsSemicolon approach (fast):
chell -c "cd /PIPELINES; ls; cat pipeline.yml"
# Total: 2-3 seconds (single connection)Execute commands from a file, enabling complex workflows, automation, and reusable procedures.
File structure:
#!/usr/bin/env chell
# Comments start with #
# Blank lines are ignored
# Commands (one per line)
pwd
ls /home
# Semicolons work within lines too
cd /PIPELINES; ls
# More commands
cat pipeline.ymlMethod 1: Explicit flag
chell -f script.chellMethod 2: Auto-detection
chell script.chell # Auto-detects file existsMethod 3: Shebang execution
chmod +x script.chell
./script.chell # Direct executionAdd #!/usr/bin/env chell to the first line to make scripts directly executable.
Example script:
#!/usr/bin/env chell
# DICOM batch processing script
# Navigate to patient directory
cd /SERVICES/PACS/PACSDCM/patient123/study
# List all DICOM files
ls *.dcm
# Process each file
cat image_001.dcm | dcmdump - > /tmp/metadata_001.txt
cat image_002.dcm | dcmdump - > /tmp/metadata_002.txt
# Verify output
ls /tmp/metadata_*.txtMake executable and run:
chmod +x dicom_batch.chell
./dicom_batch.chellFull-line comments:
# This is a comment
pwd # This is NOT a comment (inline not supported)Special cases:
#!/usr/bin/env chell # Shebang - ignored on line 1
# Comment
# Indented comment # Leading whitespace allowed
#Comment # Works without space after #Semicolons within lines:
#!/usr/bin/env chell
# Each line can have semicolons
cd /tmp; ls; pwdBlank lines for readability:
#!/usr/bin/env chell
# Section 1: Setup
mkdir /tmp/work
cd /tmp/work
# Section 2: Processing
ls /PIPELINES
cat pipeline.ymlSession state persistence:
#!/usr/bin/env chell
# Directory changes persist across lines
cd /PIPELINES
ls # Lists /PIPELINES
pwd # Shows /PIPELINESChELL provides two error handling modes: continue-on-error (default, like bash) and stop-on-error (like bash set -e).
By default, errors don’t stop execution. This matches standard bash behavior with ;.
Example:
#!/usr/bin/env chell
pwd # Succeeds
ls /nonexistent # Fails - error printed
pwd # Still executes!Output:
/home/user
ls: /nonexistent: No such file or directory
/home/userCommand line:
chell -c "pwd; ls /nonexistent; pwd"
# All three commands executeUse the -e flag to stop execution on the first error. Similar to bash set -e.
Syntax:
chell -e script.chell # Script mode
chell -c -e "cmd1; cmd2; cmd3" # Command mode
chell -f -e script.chell # Explicit -f with -eExample:
#!/usr/bin/env chell
pwd # Succeeds
ls /nonexistent # Fails - STOPS HERE
pwd # Never executesRun with -e:
chell -e script.chell
# Output:
# /home/user
# ls: /nonexistent: No such file or directory
# Error on line 3: ...
# Stopping execution due to error (use without -e to continue on error)
# (exits with code 1)Continue-on-error (default) - Use when: - Running exploratory commands - Processing batches where some failures are acceptable - Testing/debugging scripts - Want to see all errors, not just the first
Stop-on-error (-e) - Use when:
- Strict automation requirements
- CI/CD pipelines that must be reliable
- Subsequent commands depend on previous success
- Want fast-fail behavior for critical scripts
ChELL automatically determines whether a positional argument is a script file or connection target.
Detection algorithm: 1. If argument is an existing file → Script mode 2. Otherwise → Connection target
Examples:
chell script.chell # File exists → Script mode
chell cube.example.org # Not a file → Connection mode
chell user@cube.org # Not a file → Connection mode
chell /tmp/test.chell # File exists → Script mode
chell http://cube.org # Not a file → Connection modeExplicit flag overrides:
chell -f script.chell # Always script mode
chell -c "pwd" # Always command modeGoal: Extract metadata from all DICOM files in a series.
Script: dicom_metadata.chell
#!/usr/bin/env chell
# Extract DICOM metadata for all files in a series
# Navigate to series directory
cd /SERVICES/PACS/PACSDCM/patient123/study/series001
# Create output directory
mkdir /tmp/metadata
# Process each DICOM file
cat 0001.dcm | dcmdump - > /tmp/metadata/0001.txt
cat 0002.dcm | dcmdump - > /tmp/metadata/0002.txt
cat 0003.dcm | dcmdump - > /tmp/metadata/0003.txt
# Verify output
ls /tmp/metadataRun:
chmod +x dicom_metadata.chell
./dicom_metadata.chellGoal: Verify pipeline specifications across multiple users.
Script: validate_pipelines.chell
#!/usr/bin/env chell
# Validate all pipeline specifications
# Check user1 pipelines
cd /PIPELINES/user1
ls *.yml
cat analysis.yml
# Check user2 pipelines
cd /PIPELINES/user2
ls *.yml
cat processing.yml
# Summary
pwdRun with stop-on-error:
chell -e validate_pipelines.chell
# Stops if any file is missing or invalidGoal: Automated testing in GitHub Actions.
.github/workflows/test.yml:
name: ChRIS Integration Test
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install ChELL
run: npm install -g chell
- name: Run tests
env:
CHRIS_URL: ${{ secrets.CHRIS_URL }}
CHRIS_USER: ${{ secrets.CHRIS_USER }}
CHRIS_PASS: ${{ secrets.CHRIS_PASS }}
run: |
chell -c -e "connect $CHRIS_USER@$CHRIS_URL; ls /PIPELINES; pwd"Goal: Daily backup of DICOM studies.
Script: nightly_backup.chell
#!/usr/bin/env chell
# Nightly DICOM backup script
# Create date-stamped directory
mkdir /backup/$(date +%Y%m%d)
# Archive patient data
cd /SERVICES/PACS/PACSDCM/patient001
cat study_*.dcm > /backup/$(date +%Y%m%d)/patient001.tar
cd /SERVICES/PACS/PACSDCM/patient002
cat study_*.dcm > /backup/$(date +%Y%m%d)/patient002.tar
# Verify backups
ls /backup/$(date +%Y%m%d)Crontab entry:
0 2 * * * /path/to/nightly_backup.chellGoal: Complete analysis pipeline from data retrieval to result storage.
Command line:
chell -c "
cd /SERVICES/PACS/patient123;
cat ct_scan.dcm > /tmp/scan.dcm;
cd /PIPELINES/analysis;
cat pipeline.yml;
mkdir /home/user/results/$(date +%Y%m%d);
cd /home/user/results/$(date +%Y%m%d);
touch analysis_complete.txt
"Stop processing if prerequisite fails:
#!/usr/bin/env chell
# Requires -e flag to work correctly
# Check if pipeline exists (stops if not)
ls /PIPELINES/user/analysis.yml
# Only runs if above succeeds
cat /PIPELINES/user/analysis.yml
# Only runs if all above succeed
cd /SERVICES/PACS
ls *.dcmRun:
chell -e conditional.chellFrom command line:
# Run script with custom connection
chell -f process.chell user@cube.org
# Run script with physical filesystem mode
chell -f --physicalFS debug.chell
# Run script with stop-on-error
chell -e script.chellCapture script output:
chell script.chell > output.log 2>&1Filter script output:
chell script.chell | grep "ERROR"Chain with other tools:
chell -c "cat pipeline.yml" | python validate_pipeline.pyProblem: Each chell invocation has 2-3s connection/authentication overhead.
Solution: Use semicolons or scripts to batch operations.
Slow (3 invocations × 2.5s = 7.5s):
chell -c "pwd"
chell -c "ls"
chell -c "cat file.yml"Fast (1 invocation = 2.5s):
chell -c "pwd; ls; cat file.yml"Use semicolons sparingly within scripts:
#!/usr/bin/env chell
# Good - one command per line (readable)
cd /PIPELINES
ls
cat pipeline.yml
# Also good - related commands grouped
cd /tmp; mkdir work; cd workAvoid excessive scripting for simple tasks:
# Overkill - just use command mode
#!/usr/bin/env chell
pwd
# Better
chell -c "pwd"Problem:
$ chell myscript.chell
Error: Script file not found: myscript.chellSolutions:
- Use absolute path: chell /path/to/myscript.chell
- Use relative path: chell ./myscript.chell
- Check file exists: ls myscript.chell
Problem:
$ ./script.chell
bash: ./script.chell: Permission deniedSolutions:
chmod +x script.chell # Make executable
./script.chell # Try againProblem:
$ ./script.chell
/usr/bin/env: 'chell': No such file or directorySolutions:
# Check chell is installed globally
which chell
# Install globally if needed
npm install -g chell
# Or use absolute path in shebang
#!/usr/bin/node /path/to/chell/dist/index.jsProblem: Semicolon in echo command splits incorrectly.
Wrong:
chell -c "echo hello;world; pwd"
# Runs: echo hello
# world (command not found)
# pwdRight:
chell -c "echo 'hello;world'; pwd"
# Runs: echo 'hello;world'
# pwdProblem: Script continues despite errors.
Solution: Use -e flag:
chell -e script.chell # Stops on first error# Basic
chell -c "<command>"
# Multiple commands
chell -c "cmd1; cmd2; cmd3"
# Stop on error
chell -c -e "cmd1; cmd2"
# With connection
chell -c "pwd" user@cube.org
# Physical filesystem
chell -c --physicalFS "ls /actual/path"# Explicit flag
chell -f script.chell
# Auto-detect
chell script.chell
# Stop on error
chell -e script.chell
chell -f -e script.chell
# Shebang execution
chmod +x script.chell
./script.chell
# With connection
chell -f script.chell user@cube.org| Flag | Description | Works With |
|------|-------------|------------|
| -c <command> | Execute command and exit | All modes |
| -f <file> | Execute script file | Script mode |
| -e | Stop on first error | -c, -f |
| --physicalFS | Use physical paths | All modes |
| -u <user> | Username | Connection |
| -p <password> | Password | Connection |
Use descriptive filenames:
✓ dicom_batch_export.chell
✓ pipeline_validation.chell
✗ script1.chell
✗ test.chellAdd header comments:
#!/usr/bin/env chell
#
# DICOM Batch Export Script
# Purpose: Export all DICOM files for patient backup
# Author: Medical Imaging Team
# Date: 2025-01-15
#
# Usage: ./dicom_batch_export.chell
# Requires: Access to PACS serverGroup related operations:
#!/usr/bin/env chell
# === SETUP ===
mkdir /tmp/work
cd /tmp/work
# === DATA RETRIEVAL ===
cat /SERVICES/PACS/patient/study.dcm > study.dcm
# === PROCESSING ===
cat study.dcm | dcmdump - > metadata.txt
# === CLEANUP ===
cd /tmpFor production scripts:
- Always use -e flag for critical workflows
- Test without -e first to see all potential errors
- Add comments explaining expected failures
For exploratory scripts: - Use default continue-on-error - Manually check for errors you care about
Never hardcode credentials:
#!/usr/bin/env chell
# ✗ BAD
connect myuser mypassword http://cube.org
# ✓ GOOD
# Use: chell -u $USER -p $PASS script.chell
# Or provide interactivelyValidate inputs:
#!/usr/bin/env chell
# Check required directories exist
ls /PIPELINES/required
ls /SERVICES/PACS
# Script will fail early if directories missing (with -e)Document prerequisites:
#!/usr/bin/env chell
# Prerequisites:
# - Authenticated ChRIS session
# - Access to /SERVICES/PACS
# - dcmdump tool installedAdd examples:
#!/usr/bin/env chell
# Examples:
# ./script.chell # Use saved credentials
# chell -f script.chell user@url # Explicit connection
# chell -e script.chell # Stop on errors-
chell/docs/commands.adoc- Complete command reference -
chell/docs/cat.adoc- Binary file handling and DICOM workflows -
chili/docs/cli.adoc- ChILI command-line interface -
Bash manual - Semicolon and error handling behavior
Run multiple commands:
chell -c "pwd; ls; cat file.txt"Create script file:
cat > script.chell <<'EOF'
#!/usr/bin/env chell
pwd
ls
EOFRun script:
chell script.chell # Auto-detect
chell -f script.chell # Explicit
chmod +x script.chell; ./script.chell # ShebangStop on error:
chell -e script.chell
chell -c -e "cmd1; cmd2"Quote handling:
chell -c "echo 'has;semicolon'; pwd" # Single quotes
chell -c "echo \"has;semicolon\"; pwd" # Double quotes