When automating server tasks with bash scripts, the SCP command's password prompt creates a significant roadblock. Unlike SSH key authentication which works seamlessly in scripts, password-based SCP requires interactive input.
While SSH keys are indeed the recommended approach, there are valid scenarios where password authentication is necessary:
- Legacy systems with restricted key-based auth
- Temporary access to client systems
- CI/CD pipelines where key rotation isn't practical
Method 1: Using sshpass
The most straightforward solution is using sshpass
, a utility designed specifically for this purpose:
# Install sshpass first
sudo apt-get install sshpass
# Usage in script
sshpass -p "your_password" scp file.tar.gz user@remotehost:/path/to/destination
Method 2: Expect Scripting
For more complex scenarios, Expect provides greater control:
#!/usr/bin/expect
spawn scp file.tar.gz user@remotehost:/backup
expect "password:"
send "your_password\r"
expect eof
Method 3: PEM Files for AWS Environments
When working with AWS EC2 instances, you can leverage PEM files:
scp -i /path/to/key.pem file.tar.gz ec2-user@ec2-xx-xx-xx-xx.compute-1.amazonaws.com:/home/ec2-user
When implementing these solutions, always consider:
- Never hardcode passwords in scripts - use environment variables
- Set strict file permissions (600) for any credential files
- Consider using temporary credential solutions like Vault
Here's a robust implementation for production environments:
#!/bin/bash
REMOTE_USER="admin"
REMOTE_HOST="backup-server.example.com"
DEST_PATH="/backup/daily"
TEMP_PASS=$(cat /run/secrets/scp_pass)
sshpass -p "$TEMP_PASS" scp -o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
/var/backups/db_dump.tar.gz \
${REMOTE_USER}@${REMOTE_HOST}:${DEST_PATH}
- Add
-v
flag to SCP for verbose output - Test with
-C
compression for large files - Implement retry logic for unstable connections
When writing automation scripts that involve SSH or SCP operations, the password prompt interruption breaks workflow continuity. While public key authentication is the recommended approach, certain environments require password-based authentication due to security policies or legacy system constraints.
Here are three reliable methods to handle password prompts in bash scripts:
# Method 1: Using sshpass (most straightforward)
sshpass -p "your_password" scp file.tar.gz user@remotehost:/path/to/destination
# Method 2: Expect scripting (more flexible)
#!/usr/bin/expect
spawn scp file.tar.gz user@remotehost:/path/to/destination
expect "password:"
send "your_password\r"
expect eof
While these methods work, they present security risks:
- Passwords appear in process listings
- Command history may store credentials
- Script files containing passwords require strict permissions
For better security, store credentials in environment variables:
#!/bin/bash
export SSHPASS="your_password"
sshpass -e scp file.tar.gz user@remotehost:/path/to/destination
Configure ssh to use a credential helper:
Host backup-server
HostName xxx.xxx.xxx.194
User root
IdentityFile ~/.ssh/id_rsa_backup
PreferredAuthentications password
ProxyCommand sh -c "echo 'your_password' | sshpass -d0 ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no %r@%h"
Always implement proper error handling in automation scripts:
#!/bin/bash
if ! sshpass -p "your_password" scp file.tar.gz root@xxx.xxx.xxx.194:/backup; then
echo "SCP transfer failed at $(date)" >> /var/log/backup_errors.log
exit 1
fi
For production environments, consider:
- Implementing proper secret management (Vault, AWS Secrets Manager)
- Using temporary credentials with short TTL
- Regularly rotating automation credentials