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

Mar*_*rek 3 bash

我有 bash 脚本test.sh,它没有什么特别的:

#!/bin/bash
echo Hello!
Run Code Online (Sandbox Code Playgroud)

如果我像这样运行它. test.sh,它就会起作用。

kopparberg:dev marek$ . test.sh
Hello!
Run Code Online (Sandbox Code Playgroud)

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

kopparberg:dev marek$ ./test.sh 
-bash: ./test.sh: /bin/bash^M: bad interpreter: No such file or directory
Run Code Online (Sandbox Code Playgroud)

有什么不同?

小智 6

. 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)来证明情况确实如此。