运行带斜线或不带斜线的可执行 bash 脚本

运行带斜线或不带斜线的可执行 bash 脚本

我有一个test.sh没有什么特别功能的 bash 脚本:

#!/bin/bash
echo Hello!

如果我像这样运行它. test.sh,它就能工作。

kopparberg:dev marek$ . test.sh
Hello!

如果我像这样运行它./test.sh,则不会。

kopparberg:dev marek$ ./test.sh 
-bash: ./test.sh: /bin/bash^M: bad interpreter: No such file or directory

有什么不同?

答案1

. test.sh获取( )脚本和运行()脚本test.sh之间的区别./test.sh就在第一行。

如果您执行脚本,第一行只是一条注释,会被忽略。但是如果您运行它,内核会检查第一行的前两个字符,如果它们是“ #!”,则该行的其余部分将用作路径和解释器的第一个参数。也就是说,内核将查找名为的可执行文件/bin/bash,并将脚本的名称作为第一个参数传递给它。像这样:/bin/bash ./test.sh

这通常是会发生的情况,而且您说得对,它应该对您的脚本产生相同的效果。但是您的脚本包含一个问题:第一行以 DOS 行尾 (CR LF) 而不是 unix 行尾 (LF) 结尾。因此,内核看到的解释器名称/bin/bash^M并不存在于您的磁盘上(^M 代表行尾前的虚假 CR)。更糟糕的是,^M 字符通常是不可见的。

您可以通过以下方式证明这种情况cat -v test.sh(打印替换不可见的 CR 字符的 ^M)。

答案2

第一个解决方案是“source”命令的别名。

舍邦被视为源的#comment

当您使用 调用脚本时./script,shell 将使用 执行脚本舍邦 #!/bin/bash

您给出的错误似乎是 CRLF 问题,您可以运行:

dos2unix script.sh

删除 Windows 结束行。

相关内容