printf中日期命令转义及Raspberry Pi脚本创建子脚本异常问题
Got it, let's break down and solve your two key issues—getting the backup-database.sh subscript to generate correctly, and fixing the date command escaping in printf.
1. Generating Correct Subscript Content (The Heredoc Approach)
The most common reason your subscript ends up with unexpected content is that your parent script is parsing variables and command substitutions (like date) before writing them to the file. Instead of fighting with endless escapes in printf, use a here-document (heredoc)—it’s cleaner, more readable, and preserves exactly what you want to write to the subscript.
Example Working Code
Add this to your parent init script:
# Create the backup-database.sh script cat > backup-database.sh << 'EOF' #!/bin/bash # Database backup script for Raspberry Pi DB_USER="root" DB_PASS="your_secure_password" # Or use environment variables for better security BACKUP_DIR="/home/pi/db_backups" # Create backup directory if it doesn't exist mkdir -p "$BACKUP_DIR" # Run backup with timestamped filename mysqldump -u "$DB_USER" -p"$DB_PASS" --databases your_database_name > "${BACKUP_DIR}/backup_$(date +%Y%m%d_%H%M%S).sql" # Optional: Compress the backup to save space gzip "${BACKUP_DIR}/backup_$(date +%Y%m%d_%H%M%S).sql" EOF # Make the subscript executable chmod +x backup-database.sh
Why This Works:
- The
'EOF'(quoted delimiter) tells the shell to treat everything between<< 'EOF'andEOFas literal text. No variables or commands in the subscript will be parsed by the parent script—they’ll be written exactly as-is. - If you do need to pass a variable from the parent script to the subscript (e.g., a dynamic backup directory), just remove the quotes around
EOF:PARENT_BACKUP_DIR="/home/pi/backups" cat > backup-database.sh << EOF #!/bin/bash BACKUP_DIR="$PARENT_BACKUP_DIR" # Rest of the script... EOF
2. Fixing Date Escaping If You Must Use printf
If you prefer sticking with printf instead of heredoc, you need to properly escape special characters to prevent the parent script from executing them prematurely:
- Escape
$with\$to keep variables intact for the subscript. - Use
\$(date ...)(POSIX command substitution) instead of backticks (`date`) because it’s easier to escape. - Double up
%as%%—sinceprintfuses%for format specifiers, this tells it to output a literal%.
Corrected printf Example:
printf '#!/bin/bash\n\ DB_USER="root"\n\ DB_PASS="your_secure_password"\n\ BACKUP_DIR="/home/pi/db_backups"\n\ mkdir -p "$BACKUP_DIR"\n\ mysqldump -u "$DB_USER" -p"$DB_PASS" your_database_name > "${BACKUP_DIR}/backup_\$(date +%%Y%%m%%d_%%H%%M%%S).sql"\n' > backup-database.sh
Again, heredoc is almost always the better choice here—this printf approach gets messy fast with longer scripts.
Final Check
After running your init script, verify the content of backup-database.sh with cat backup-database.sh—you should see the exact script you intended, with the date command intact and variables properly set.
内容的提问来源于stack exchange,提问作者TwitchBronBron

