~5 min read • Updated Feb 15, 2026
1. Overview
cPanel & WHM allows advanced users to create custom transport scripts for sending backups to destinations that are not supported by default. These scripts integrate with WHM’s Backup Configuration interface:
WHM » Home » Backups » Backup Configuration
Warning: Custom transport scripts are intended only for advanced users. If you prefer simpler options, WHM already supports:
- Local directory
- Amazon S3™
- Backblaze B2
- FTP
- Google Drive™
- Rsync
- S3 Compatible
- SFTP
- WebDAV
2. What Is a Custom Transport Script?
A custom transport script is a user‑created script that handles file transfers for a custom backup destination. You provide the script’s absolute path in the Script field when selecting the Custom destination type in WHM’s Additional Destinations section.
3. Script Operation Rules
Your script must follow these rules:
- The script runs once per command. li>The script cannot store state between commands.
- Connections are not reused; each command triggers a new connection.
- The system passes arguments to the script in this order:
1. Command name
2. Current directory
3. Command-specific parameters
4. Host
5. Username
Password is passed through the environment variable PASSWORD.
4. Required Script Commands
Your script must implement the following commands:
| Command | Description | Parameters |
|---|---|---|
| chdir | Changes directory on the remote destination. | $path |
| delete | Deletes a file on the remote destination. | $path |
| get | Downloads a remote file to the local server. | $dest_root_dir, $dest_file, $local_file |
| ls | Lists files (same as ls -l). |
$path |
| mkdir | Creates a directory on the remote destination. | $path |
| put | Uploads a local file to the remote destination. | $dest_root_dir, $dest_file, $local_file |
| rmdir | Deletes a directory recursively. | $path |
Warning: Always verify paths before deleting. Passing / will cause severe system damage.
5. Script Structure
5.1 Required Perl Modules
use strict;
use warnings;
use Cwd qw(getcwd abs_path);
use File::Spec;
use File::Copy;
use File::Path qw(make_path remove_tree);
use autodie qw(:all copy);
5.2 Command Hash
The script must define a hash that maps commands to subroutines:
my %commands = (
put => \&my_put,
get => \&my_get,
ls => \&my_ls,
mkdir => \&my_mkdir,
chdir => \&my_chdir,
rmdir => \&my_rmdir,
delete => \&my_delete,
);
5.3 Argument Handling
my ( $cmd, $local_dir, @args, $host, $user ) = @ARGV;
my $password = $ENV{'PASSWORD'};
usage() unless exists $commands{$cmd};
6. Command Implementations
6.1 put — Upload a File
sub my_put {
my ( $local, $remote, $host, $user ) = @_;
my $password = $ENV{'PASSWORD'};
$remote = convert_path($remote);
my ( undef, $dir, undef ) = File::Spec->splitpath($remote);
make_path($dir) unless ( $dir and -d $dir );
copy( $local, $remote );
return;
}
6.2 get — Download a File
sub my_get {
my ( $remote, $local, $host, $user ) = @_;
my $password = $ENV{'PASSWORD'};
$remote = convert_path($remote);
copy( $remote, $local );
return;
}
6.3 ls — List Files
sub my_ls {
my ( $path, $host, $user ) = @_;
my $password = $ENV{'PASSWORD'};
$path = convert_path($path);
my $ls = `ls -al $path`;
$ls =~ s|^total[^\n]*\n||;
print $ls;
return;
}
6.4 mkdir — Create Directory
sub my_mkdir {
my ( $path, $recurse, $host, $user ) = @_;
my $password = $ENV{'PASSWORD'};
$path = convert_path($path);
make_path($path);
die "Failed to create $path" unless -d $path;
return;
}
6.5 chdir — Change Directory
sub my_chdir {
my ( $path, $host, $user ) = @_;
my $password = $ENV{'PASSWORD'};
$path = convert_path($path);
chdir $path;
print get_sub_directory( getcwd() ) . "\n";
return;
}
6.6 rmdir — Remove Directory
sub my_rmdir {
my ( $path, $host, $user ) = @_;
my $password = $ENV{'PASSWORD'};
$path = convert_path($path);
remove_tree($path);
die "$path still exists" if -d $path;
return;
}
6.7 delete — Delete File
sub my_delete {
my ( $path, $host, $user ) = @_;
my $password = $ENV{'PASSWORD'};
$path = convert_path($path);
unlink $path;
return;
}
7. Basic Error Checking
usage() if ( @ARGV < 2 );
sub usage {
my @cmds = sort keys %commands;
print STDERR "This script implements a custom backup destination.\n";
print STDERR "Required arguments: cmd, local_dir, cmd_args\n";
print STDERR "Valid commands: @cmds\n";
exit 1;
}
8. Execute the Command
$commands{$cmd}->(@args);Conclusion
Custom transport scripts give advanced users full control over how backups are transferred to remote destinations. By following the required structure and implementing all mandatory commands, you can integrate any custom storage system with WHM’s backup framework.
Written & researched by Dr. Shahin Siami