When working with long-running processes on Linux servers, we often turn to nohup
to keep them running after logout. However, this becomes problematic when the command requires initial interactive input - like SSH passwords for rsync or confirmation prompts for database operations.
The standard approach:
nohup rsync -avz user@remote:/path/ /local/path/ &
fails because:
- nohup redirects stdin to /dev/null
- Interactive prompts get suppressed
- The process hangs waiting for unavailable input
1. Using expect to Automate Input
The expect
utility can handle interactive prompts programmatically:
#!/usr/bin/expect -f
spawn nohup rsync -avz user@remote:/path/ /local/path/
expect "password:"
send "your_password\r"
expect eof
2. SSH Key Authentication
For SSH-based commands like rsync, the cleanest solution is key-based authentication:
ssh-keygen -t rsa
ssh-copy-id user@remote
nohup rsync -avz -e ssh user@remote:/path/ /local/path/ &
3. Using tmux or screen
Terminal multiplexers provide a more robust alternative:
tmux new -s rsync_session
rsync -avz user@remote:/path/ /local/path/
# Detach with Ctrl+B, D
# Reattach later with tmux attach -t rsync_session
4. Input Redirection with Here Document
For simple cases where you can provide all input upfront:
nohup command.sh << EOF
input_line_1
input_line_2
EOF
Combining sshpass with nohup
When you must use password authentication:
nohup sshpass -p 'password' rsync -avz user@remote:/path/ /local/path/ &
Note: This exposes the password in process listings. Consider using SSHPASS
environment variable instead.
Systemd Service Units
For production systems, creating a service is often better:
[Unit]
Description=Rsync Backup Service
[Service]
Type=simple
ExecStart=/usr/bin/rsync -avz user@remote:/path/ /local/path/
Restart=on-failure
[Install]
WantedBy=multi-user.target
When dealing with automated authentication:
- Always prefer SSH keys over passwords
- Set strict permissions on any files containing credentials (chmod 600)
- Consider using a secrets management system for production
- Regularly rotate automated credentials
- Check
nohup.out
for error messages - Verify process is running with
ps aux | grep [r]sync
- Test commands interactively before nohup
- Consider logging output to syslog for better visibility
When running processes in the background using nohup
, interactive input requirements create a fundamental problem. The classic example is rsync
requiring SSH password authentication - the prompt appears, but since the process is detached from the terminal, there's no way to provide input.
Here are three practical solutions to handle this scenario:
# 1. Using SSH keys instead of password authentication
rsync -avz -e "ssh -i /path/to/private_key" user@remote:/path/ /local/path/ >> rsync.log 2>&1 &
# 2. Using expect to automate the password input
#!/usr/bin/expect -f
spawn nohup rsync -avz user@remote:/path/ /local/path/
expect "password:"
send "your_password\r"
expect eof
# 3. Using password-less authentication methods
# For rsync specifically, you can use:
rsync --password-file=/path/to/password/file user@remote::module /local/path/
The most robust solution for rsync involves setting up SSH key authentication:
# Generate SSH key pair if you haven't already
ssh-keygen -t rsa -b 4096
# Copy public key to remote server
ssh-copy-id -i ~/.ssh/id_rsa.pub user@remote
# Now you can run rsync without password prompt
nohup rsync -avz user@remote:/path/ /local/path/ > rsync.log 2>&1 &
If you absolutely need to provide a password interactively, consider using screen
or tmux
instead:
# Using screen
screen -S rsync_session
rsync -avz user@remote:/path/ /local/path/
# Press Ctrl+A then D to detach
# Later reattach with screen -r rsync_session
While the above solutions work, remember that hardcoding passwords in scripts (like with expect) is generally discouraged. SSH keys or password files with restricted permissions are more secure approaches.