获取脚本时“无法 cd 到 /home/user”

获取脚本时“无法 cd 到 /home/user”

我有这个脚本:

echo $HOME
cd $HOME
cd /
cd /usr/local/src/

当我这样运行时

. script.sh

我得到这个输出:

/home/user
: No such file or directory
: No such file or directory
: No such file or directory

如果我正常运行它(我#!/bin/bash在第一行之前添加)

sh script.sh

我得到这个输出:

: not found.sh: 2: script.sh
/home/user
script.sh: 3: Can't cd to /home/user
script.sh: 4: Can't cd to /
script.sh: 5: Can't cd to /usr/local/src/

$HOME该脚本每次都从目录运行。如果我从 shell 中一一运行每个命令,它执行时不会出现问题(cd $HOME从内部调用$HOME根本不会更改目录)。

我必须做什么才能使这项工作成功?

答案1

您的脚本中有 CR (^M) 字符。将其转换为具有 Unix 行尾(仅 LF)。以便携的方式:

tr -d '\r' < your_script > output_script

基于 Olivier Dulac 对 CR 字符发生情况的评论的一些解释: 首先,在 shell 语言中,CR 字符不被视为特殊字符,例如不被视为空格并且不被忽略。我写如下^M

  • 该行中,输出了后面跟着换行echo $HOME^M的内容。输出 CR 字符将光标放在第一列上,但由于紧随其后的是换行符,因此这没有明显的效果。$HOME^M

  • 在该cd $HOME^M行中,由于 和 CR 字符之间没有空格$HOME,因此它们都在同一个参数中$HOME^M,并且该目录不存在。在错误消息中,$HOME只是输出后面的 CR 字符,将光标放在第一列上,这样行首就会被消息的其余部分覆盖(如果有的话): ": No such file or directory" with bash (你的第一个例子),没有破折号(你的第二个例子sh script.sh#!/bin/bash因为你明确要求运行脚本而被忽略sh,这在你的情况下似乎是破折号)。错误消息完全取决于 shell。例如,zsh 检测到 CR 字符不可打印并输出如下消息:

    cd: 没有这样的文件或目录: /usr/local/src/^M

(使用字符“^”和“M”,而不是 CR 字符),这使得人们可以更轻松地检测问题的原因。否则,您需要将 stderr 重定向/管道到某个可以显示特殊字符的实用程序,例如cat -veOlivier 建议的,或者到hd,它给出流的字节序列。

答案2

如果您使用,set -x您会注意到为什么获取文件失败:

$ . test.sh
+ . test.sh
++ echo $'/home/braiam\r'
/home/braiam
++ cd $'/home/braiam\r'
: No such file or directory
++ cd $'/\r'
: No such file or directory
++ cd $'/usr/local/src/\r'
: No such file or directory

正如vinc17所说,只需删除\r脚本的一部分就可以了。您可以使用他的解决方案,或者dos2unix script.sh也使用 ,sed -i 's/\r//' script.sh

答案3

您也可以使用以下命令删除 CR 字符。

perl -p -i -e "s/\r//g" script.sh

如果您正在使用/维姆,你可以这样做,

:set ff=unix

答案4

我遇到了同样的问题,我通过将 EOL 字符转换为 UNIX 格式来修复它。一个简单的方法是:

  • 将文件加载到 Notepad++ 中
  • 选择所有要转换的文本(Ctrl + A)
  • 编辑 > EOL 转换 > UNIX
  • 保存文件

如果已经是 UNIX 格式,请选择另一种格式 (Windows),然后返回 UNIX

相关内容