我想要一个带有时间戳后缀的 bash 脚本来重命名 MySQL 数据库。
DB=database
DATE=$(date +%Y%m%d_%H%M%S)
(
echo "CREATE DATABASE $DB_$DATE;"
echo "USE $DB;"
echo 'SHOW TABLES;' | while read TABLE; do
echo "RENAME TABLE $DB.$TABLE TO $DB_$DATE.$TABLE;"
done
) | mysql ${DB} -N
exit 0;
错误:
'RENAME TABLE database.SHOW TABLES; TO database_20191205_121556.SHOW TABLES;;'
ERROR 1064 (42000) at line 3: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'TABLES' at line 1
echo 'SHOW TABLES;' | while read TABLE; do
这不会遍历表列表,这只是遍历单个字符串"SHOW TABLES"。
您可能希望:
mysql ${DB} -Nse "SHOW TABLES" | while read TABLE; do
重新发表您的评论:
请考虑以下两个命令:
ls | while read filename ; do echo $filename ; done
echo ls | while read filename ; do echo $filename ; done
请尝试这两个命令。不是在脚本中,而是在您的外壳中。输出是什么?
仅回显包含命令的字符串不会运行该命令。
仅仅将字符串读入您命名$TABLE
变量并不意味着它包含表名。
好的,我正在尝试您的脚本,但管道cat
而不是mysql
:
DB=database
DATE=$(date +%Y%m%d_%H%M%S)
(
echo "CREATE DATABASE $DB_$DATE;"
echo "USE $DB;"
echo 'SHOW TABLES;' | while read TABLE; do
echo "RENAME TABLE $DB.$TABLE TO $DB_$DATE.$TABLE;"
done
) | cat
exit 0;
这样我们可以看到输出:
CREATE DATABASE 20191205_174532;
USE database;
RENAME TABLE database.SHOW TABLES; TO 20191205_174532.SHOW TABLES;;
前两个 echo 语句输出CREATE
和USE
的合法 SQL 语句。没关系。
但是while
循环不是读取表名,而是读取一个字符串:"SHOW TABLES"并假设它是一个表名。但它不是一个表名,它只是一个字符串,恰好是字面意思是"显示表"。它不是运行"SHOW TABLES"的输出,它只是字符串本身。
我不知道还能怎么解释。
哦,第二个问题与循环无关。
在 shell 中,_
是变量名中的有效字符。所以$DB
与$DB_
不同.如果在后面带有_
字符的字符串中使用变量名称,则应分隔变量名称。
echo "CREATE DATABASE ${DB}_${DATE};"
你写它的方式,它试图替换$DB_
的值,这是一个不存在的变量。