这是我的 bash 脚本,它从 php 发送一个变量:
STRING1="/opt/lampp/htdocs/dev/img/$VAR1"
mv $STRING1 "/opt/lampp/htdocs/dev/newlocation/"
Run Code Online (Sandbox Code Playgroud)
出于某种原因,它在 $STRING1 的末尾放置了“\r”并且找不到该文件,因为它将是“my_picture.jpg\r”形式的内容
任何帮助表示赞赏!
Nic*_*ton 16
Bash 期望脚本中的行尾总是并且只是一个换行符 (\n),Unix 风格,而不是像您通常在 Windows 上看到的回车换行符组合 (\r\n)。Bash 认为 \r 字符只是字符串末尾的一个普通字符。(双引号字符串后面的字符只是连接到末尾。)
正如 Ignacio 所建议的,解决方案是修复您的脚本以消除 \r 字符。 dos2unix是一种方式。另一种方法是tr -d '\r' < infile > outfile用作过滤器。
这显然是为了像我这样的其他谷歌员工,而不是 OP,因为它已经 5 年多了。但是这个解决方案当时也存在。
您可以尝试使用 bash 替换从看起来像 ${varname%%pattern} 的字符串末尾去除最大的模式,更多信息请点击此处:
http://tldp.org/LDP/abs/html/string-manipulation.html
它应该比产生另一个像 tr 这样的进程来处理它要快。
VARNAME=$'a_bad_filename\r'
VARNAME="${VARNAME%%[[:cntrl:]]}"
Run Code Online (Sandbox Code Playgroud)
这是严格限制的 bash 模式匹配的参考(它不是真正的正则表达式,更像是“like”或“glob”表达式)。至于为什么回车是在控件类而不是空格类中,我不确定。它在其他语言中被视为空白。如果不通过“shopt -s extglob”启用扩展模式匹配,则无法在 bash 中指定像“此字符重复 0 次或多次”这样的简单结构。我还发现
printf "%q" "${VARNAME}"
Run Code Online (Sandbox Code Playgroud)
.. 除了set -vx显示/测试回车。
我在对标准(非 cygwin)版本的 python 输出使用 cygwin bash 时遇到了这个问题;我很困惑为什么我没有看到更多关于如何解决它的信息。