如何在 bash 脚本执行期间正确删除 '\r' 符号

如何在 bash 脚本执行期间正确删除 '\r' 符号

我有一个 bash 脚本:

#!/bin/bash

set -x
PATH=/bin:/sbin:/usr/bin:/usr/sbin

server="$1"
curdate=$(date +'%Y%m%d')
sshoptions="-i /root/.ssh/backup -q -t"

mysqluser="root"
mysqlpassword=$(ssh $sshoptions root@$server "cat /root/.my.passwd")
mysqlaccess="-u$mysqluser -p$mysqlpassword"
mysqldatabases=$(ssh $sshoptions root@$server "mysql $mysqlaccess -B -N -e \"SHOW DATABASES;\" | grep -E -v 'information_schema|mysql'")
mysqldump="mysqldump $mysqlaccess --opt --skip-comments -B -R"

for db in $mysqldatabases; do
    echo "$(date +"%Y/%m/%d %H:%M:%S") mysqldump: dump $db"
    ssh $sshoptions root@$server "$mysqldump $db" | gzip -9 > $db_$curdate.sql.gz
done

如您所见,它用于 MySQL 数据库的备份(我计划将它与 rsnapshot 一起使用)。

当我运行此脚本时出现一个问题:

# bash /etc/rsnapshot.scripts/mysql.sh sugar.dev.host.com
+ PATH=/bin:/sbin:/usr/bin:/usr/sbin
+ server=sugar.dev.host.com
++ date +%Y%m%d
+ curdate=20130321
+ sshoptions='-i /root/.ssh/backup -q -t'
+ mysqluser=root
++ ssh -i /root/.ssh/backup -q -t [email protected] 'cat /root/.my.passwd'
+ mysqlpassword=XXXXXX
+ mysqlaccess='-uroot -pXXXXXX'
++ ssh -i /root/.ssh/backup -q -t [email protected] 'mysql -uroot -pXXXXXX -B -N -e "SHOW DATABASES;" | grep -E -v '\''information_schema|mysql'\'''
+ mysqldatabases=$'sugarcrm\r'
+ mysqldump='mysqldump -uroot -pXXXXXX --opt --skip-comments -B -R'
+ for db in '$mysqldatabases'
++ date '+%Y/%m/%d %H:%M:%S'
' echo '2013/03/21 17:41:04 mysqldump: dump sugarcrm
2013/03/21 17:41:04 mysqldump: dump sugarcrm
+ gzip -9
' ssh -i /root/.ssh/backup -q -t [email protected] 'mysqldump -uroot -pXXXXXX --opt --skip-comments -B -R sugarcrm

因此,我得到了从解析的 SQL 查询中获得的 '\r' 符号。我在转储中看到此错误:

mysqldump:出现错误:1102:选择数据库时数据库名称“sugarcrm^M”不正确

我该如何正确地修剪它?我说的“正确”是指我们不能立即修剪“mysqldatabases”变量的值。因为这里有一个数据库,但如果有两个或更多,stdout 就会出错。所以我的观点是,我们必须在“for”循环中修剪符号。

请建议一个正确的方法。谢谢。

答案1

另外一种方式:

sed

for db in '$mysqldatabases'; do
    db=$(echo $db|sed 's/\r$//')

bash 本机

for db in '$mysqldatabases'; do
    db=${db//\r/}

答案2

我将首先尝试对 mysql 使用原始参数--raw 或 -r。

--raw,-r

           对于表格输出,列周围的“装箱”可启用一列
           值来区分。对于非表格输出(如
           就像在批处理模式下生成的那样,或者当 --batch 或 --silent 选项
           给定),特殊字符会在输出中被转义,以便它们可以
           很容易识别。换行符、制表符、NUL 和反斜杠都写在
           如 \n、\t、\0 和 \\。--raw 选项可禁用此字符
           逃跑。

           以下示例演示了表格输出与非表格输出
           并使用原始模式来禁用转义:

               %mysql
               mysql> 选择 CHAR(92);
               +----------+
               | 字符(92) |
               +----------+
               | \ |
               +----------+
               %mysql-s
               mysql> 选择 CHAR(92);
               字符(92)
               \\
               %mysql-s-r
               mysql> 选择 CHAR(92);
               字符(92)
               \

如果这不起作用我会用 tr 删除它们例如

tr -d '\r'

答案3

\r(又名,^M正如您所发现的)是回车符(ASCII 控制字符 CR)。某些操作系统将其用作行尾的一部分,例如 Windows 以\r\n(CR、NL,如 ASCII 所预期的那样)结束行,Mac 以 结束行\n\r,而 Unix 创建者凭借其无穷智慧,通过以 结束行节省了一个字节\n。因此,您在 Unix/Linux 上按照 Windows/DOS 约定处理文本。有一个名为 的工具dos2unix可以修复行尾(在 Fedora 中,该软件包名为dos2unix)。请小心,仅仅剥离\r可能会损坏(二进制)文件。

相关内容