我有一个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 结束行。