我有以下脚本:
#!/bin/sh
#parameters definition
ROOT_PATH=/var/www/
msql_psw="cc"
mysql_login="bb"
mysql_db_name="aa"
echo START MYSQL DUMP
NOW=$(date +"%Y-%m-%d")
SQLFILE="log-$NOW.sql"
mysqldump --add-drop-table -u "$mysql_login" --password="$mysql_psw" "$mysql_db_name" > "$ROOT_PATH/$SQLFILE"
Run Code Online (Sandbox Code Playgroud)
当它与 一起运行时sh -x,它会给出空行的命令未找到错误,甚至非空行也无法正常工作:
sh -x export_db.sh
+ $'\r'
: command not found2:
+ ROOT_PATH=$'/var/www/\r'
+ msql_psw=$'cc\r'
+ mysql_login=$'bb\r'
+ mysql_db_name=$'aa\r'
+ $'\r'
: command not found8:
+ echo START MYSQL $'DUMP\r'
START MYSQL DUMP
+ $'\r'
: command not found10:
++ date +%Y-%m-%d
+ NOW=$'2014-10-02\r'
+ SQLFILE=$'log-2014-10-02\r.sql\r'
+ mysqldump --add-drop-table -u $'bb\r' --password= $'aa\r'
: No such file or directory/www/
Run Code Online (Sandbox Code Playgroud)
$'\r是 shell 编写 CR 字符的方式——回车符。DOS 格式的文本文件以 CRLF 结尾——用 shell 的说法是 ,$'\r\n'而 UNIX 文本文件仅以 $ 结尾\n。因此,当 UNIX 读取 DOS 格式的文本文件时,每一行的\r末尾都会多一个 $。
除此之外,还有一些注释(在某些地方,仅与问题的先前版本相关):
赋值中不使用扩展运算符,因此
$ROOT_PATH=/var/www/
Run Code Online (Sandbox Code Playgroud)
需要是
ROOT_PATH=/var/www
Run Code Online (Sandbox Code Playgroud)
除此之外——在所有扩展上使用引号。那是:
mysqldump \
--add-drop-table \
-u "$mysql_login" \
--password="$mysql_psw" \
"$mysql_db_name" \
>"$ROOT_PATH/$SQLFILE"
Run Code Online (Sandbox Code Playgroud)
否则,变量将被 IFS、glob-expanded 等分割。
最后 - 当做出如此大胆的声明,即变量没有被替换时,请尝试通过set -x在脚本中使用(或以 启动它#!/bin/sh -x,或以 手动运行它sh -x yourscript)来证明它,以记录 shell 实际运行的命令展开后调用。