Batch Scripting

AeroFTP CLI includes a built-in batch scripting engine for automating multi-step file operations. Batch scripts use the .aeroftp file extension and provide variables, error policies, quoting, and all core CLI operations in a simple line-oriented format.

Running a Batch Script

aeroftp batch deploy.aeroftp
aeroftp batch backup.aeroftp --verbose
aeroftp batch script.aeroftp --json

When --json is specified, all command output within the script is emitted as structured JSON to stdout, with errors going to stderr.

Script Format

Each line contains exactly one command. Blank lines and lines starting with # are ignored as comments.

# This is a comment
SET host=sftp://admin@myserver.com

# Blank lines are fine for readability

CONNECT $host
LS $host/var/www/

All 17 Commands

CommandSyntaxDescription
SETSET name=valueDefine a variable
ECHOECHO message textPrint a message to stdout
ON_ERRORON_ERROR CONTINUE or ON_ERROR FAILSet error handling policy
CONNECTCONNECT urlTest server connectivity
DISCONNECTDISCONNECTClose the current connection
LSLS url [options]List remote directory contents
GETGET url [-o local] [-r]Download file(s) from server
PUTPUT url local [-r]Upload file(s) to server
RMRM urlRemove a remote file or directory
MVMV source destinationMove or rename a remote file
CATCAT urlDisplay remote file contents
STATSTAT urlShow file metadata (size, mtime, permissions)
FINDFIND url "pattern"Search for files matching a glob pattern
DFDF urlShow storage quota and disk usage
MKDIRMKDIR urlCreate a remote directory
TREETREE url [-d depth]Display recursive directory tree
SYNCSYNC remote local [options]Synchronize directories

Variable Expansion

Defining Variables

Use SET to define variables. Variable names support alphanumeric characters and underscores:

SET host=sftp://deploy@prod.example.com
SET remote_path=/var/www/html
SET local_path=./dist
SET version=2.5.0

Referencing Variables

Reference variables with $name or ${name}:

ECHO Deploying version $version to $host
PUT $host$remote_path/ $local_path/ -r
GET $host/backups/db-$version.sql.gz -o ./backup.sql.gz

Expansion Rules

  • Single-pass expansion: Variables are expanded exactly once. There is no recursive expansion, which prevents injection attacks where a variable value contains $ references.
  • Undefined variables: If a variable is not defined, the $name literal is left as-is in the command string.
  • Literal dollar sign: Use $$ to produce a literal $ character.
SET price=100
ECHO The cost is $$${price}   # Output: The cost is $100
ECHO Undefined: $missing       # Output: Undefined: $missing

Maximum Variables

A single script may define up to 256 variables. Exceeding this limit causes the script to abort with an error.

Quoting

The batch engine uses shell-like quoting rules:

Quote TypeBehaviorExample
Double quotes "..."Preserves spaces, expands variablesPUT $host/dir/ "my file.txt"
Single quotes '...'Preserves spaces, no variable expansionECHO 'Literal $var'
No quotesSplit on whitespace, expands variablesPUT $host/dir/ file.txt

Double quotes are essential when paths or filenames contain spaces:

SET server=sftp://user@host
PUT $server/uploads/ "Q1 Report (Final).pdf"
GET $server"/path with spaces/data.csv" -o ./data.csv

Error Handling

ON_ERROR Policies

Control how the script reacts when a command fails:

ON_ERROR FAIL       # Abort the entire script on any error
ON_ERROR CONTINUE   # Log the error and proceed to the next line

The default policy is CONTINUE (changed from FAIL as of v2.9.2). You can switch policies at any point in the script, which allows critical sections to abort while optional operations continue:

# Critical: must succeed
ON_ERROR FAIL
CONNECT $server
SYNC $server/www/ ./dist/

# Optional: failure is acceptable
ON_ERROR CONTINUE
GET $server/var/log/access.log -o ./logs/access.log
GET $server/var/log/error.log -o ./logs/error.log

# Critical again
ON_ERROR FAIL
ECHO Deploy verification...
LS $server/www/index.html

Exit Codes

When a script aborts due to ON_ERROR FAIL, the CLI exits with the exit code of the failed command (see Installation for the full exit code table).

Script Limits

ConstraintValueRationale
Maximum script file size1 MBPrevents accidental loading of large files
Maximum variables256Memory safety bound
Variable expansionSingle-passInjection prevention
Line lengthUnlimitedNo artificial cap
Command nestingNot supportedFlat execution model

Real-World Example: Nightly Backup

# backup.aeroftp — Nightly backup of production server
# Run: aeroftp batch backup.aeroftp
# Cron: 0 2 * * * /usr/bin/aeroftp batch /opt/scripts/backup.aeroftp >> /var/log/aeroftp-backup.log 2>&1

SET server=sftp://backupuser@prod.example.com
SET remote=/var/www/html
SET backup_dir=./backups/nightly

# Critical: database and website must succeed
ON_ERROR FAIL
ECHO [1/4] Connecting to production server...
CONNECT $server

ECHO [2/4] Syncing website files...
SYNC $server$remote/ $backup_dir/www/

ECHO [3/4] Downloading database dump...
GET $server/var/backups/db-latest.sql.gz -o $backup_dir/db-latest.sql.gz

# Optional: logs are nice to have but not critical
ON_ERROR CONTINUE
ECHO [4/4] Downloading server logs...
GET $server/var/log/nginx/access.log -o $backup_dir/access.log
GET $server/var/log/nginx/error.log -o $backup_dir/error.log

ECHO Checking remote disk usage...
DF $server/

ECHO Backup complete.

Schedule it via cron:

# crontab -e
0 2 * * * /usr/bin/aeroftp batch /opt/scripts/backup.aeroftp >> /var/log/aeroftp-backup.log 2>&1

Real-World Example: Multi-Server Deployment

# deploy.aeroftp — Deploy build artifacts to 3 servers
# Run: aeroftp batch deploy.aeroftp

SET build_dir=./dist
SET app_path=/var/www/app

SET staging=sftp://deploy@staging.example.com
SET prod_eu=sftp://deploy@eu.prod.example.com
SET prod_us=sftp://deploy@us.prod.example.com

ON_ERROR FAIL

ECHO === Deploying to staging ===
CONNECT $staging
SYNC $staging$app_path/ $build_dir/ -r

ECHO === Deploying to EU production ===
CONNECT $prod_eu
SYNC $prod_eu$app_path/ $build_dir/ -r

ECHO === Deploying to US production ===
CONNECT $prod_us
SYNC $prod_us$app_path/ $build_dir/ -r

ECHO All 3 servers deployed successfully.

CI/CD Example: GitHub Actions

name: Deploy via AeroFTP Batch

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install AeroFTP CLI
        run: |
          wget -q https://github.com/axpnet/aeroftp/releases/latest/download/aeroftp_amd64.deb
          sudo dpkg -i aeroftp_amd64.deb

      - name: Build project
        run: npm ci && npm run build

      - name: Create batch script
        run: |
          cat > deploy.aeroftp << 'SCRIPT'
          SET server=sftp://${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}
          SET remote=/var/www/html

          ON_ERROR FAIL
          CONNECT $server
          SYNC $server$remote/ ./dist/
          ECHO Deploy complete.
          SCRIPT

      - name: Deploy
        run: aeroftp batch deploy.aeroftp --json
        env:
          NO_COLOR: 1

Tip: Always use ON_ERROR FAIL for critical operations and switch to ON_ERROR CONTINUE for optional steps. This gives fine-grained control over script abort behavior without needing conditional logic.