linux下的shebang不会拆分参数

Amo*_*ous 3 linux bash shell ubuntu gnu-coreutils

我有kotlin脚本(但它可以是带参数的任何Linux命令),例如:

#!/usr/bin/env kotlinc -script
println("hello world")
Run Code Online (Sandbox Code Playgroud)

当我在Ubuntu中运行它时,我得到:

/usr/bin/env: ‘kotlinc -script’: No such file or directory
Run Code Online (Sandbox Code Playgroud)

但是当我在命令行中运行时:

/usr/bin/env kotlinc -script
Run Code Online (Sandbox Code Playgroud)

有用.找到路径是没有问题的,因为脚本:

#!/usr/bin/env kotlinc
println("hello world")
Run Code Online (Sandbox Code Playgroud)

作品

出于某种原因,Ubuntu "#!/usr/bin/env kotlinc -script"将其"kotlinc -script"视为单一参数.但只在shell脚本标题中.

我需要明确的运行我的剧本"#!/usr/bin/env kotlinc -script",因为我希望它在哪里其他发行结束的环境中正常运行"kotlin"$PATH.

在Ubuntu coreutils中是否有错误或某事?有办法解决吗?

hek*_*mgl 6

在Linux上,您不能通过shebang行传递多个参数.所有参数都将作为单个字符串传递给可执行文件:

#!/bin/foo -a -b -c
Run Code Online (Sandbox Code Playgroud)

将传递一个选项"-a -b -c" /bin/foo,加上文件的内容.就像你打电话:

/bin/foo '-a -b -c' contents-of-file.txt
Run Code Online (Sandbox Code Playgroud)

现在大多数unix派生的行为应该是相同的,但它可以有所不同,我还没有测试过它们:)

很难找到适当的文档,我能很快找到的最好的是:https://www.in-ulm.de/~mascheck/various/shebang/#splitting


作为一种解决方法,您通常会创建一个shell包装器:

#!/bin/bash
exec kotlin --arg1 --arg2 ... /path/to/kotlin-script
Run Code Online (Sandbox Code Playgroud)

  • 并且为了混淆参数,一些像perl这样的解释器会重新处理shebang行本身. (3认同)

小智 6

检查您的 coreutils 版本:

apt-cache policy coreutils
Run Code Online (Sandbox Code Playgroud)

从 coreutils 8.30 开始,您将能够使用:

#!/usr/bin/env -S command arg1 arg2 ...
Run Code Online (Sandbox Code Playgroud)

您可能想要升级您的 coreutils