linux - 带有 env shebang 的脚本卡在 Linux 上

标签 linux

我们有一个看起来像这样的脚本:

#!/usr/bin/env node --unhandled-rejections=strict
console.log("Hi!");
这在我的笔记本电脑 (OSX) 上运行良好,但是当我们在 Linux 上运行它时,它就挂了。使用 strace 我们可以看到它不断加载 libc 并执行
execve("./foo.sh", ["./foo.sh"], ["YARN_VERSION=1.22.4", "HOSTNAME=307d861c7c1a", "PWD=/", "HOME=/root", "NODE_VERSION=12.18.1", "TERM=xterm", "SHLVL=1", "PATH=/usr/local/sbin:/usr/local/"..., "_=/usr/bin/strace", "node --unhandled-rejections=stri"...]) = 0
我们可以在这里看到 env 的参数被解释为环境变量。我们也知道“node --unhandled-rejections=strict”作为单个参数传入。
我们可以通过创建两个脚本来查看 OSX 中的差异。 b1.sh:
args=("$@")
echo \"${args[0]}\" \"${args[1]}\" \"${args[2]}\"
和 b2.sh
#!/usr/bin/env /tmp/b1.sh foo=bar
当我们在 OSX 上运行 b2.sh 时,我们得到
"foo=bar" "./b2.sh" ""
在 Linux 上它也会挂起。
所以很明显,在 Linux 和 OSX 中,参数传递给 env 的方式不同。在 OSX 中,“/tmp/b1.sh”和“foo=bar”是单独的参数。在 Linux 中,它们作为相同的参数传递。
但是为什么这会导致 env 一遍又一遍地执行相同的代码?

最佳答案

您可以使用 -Senv拆分 node --unhandled-rejections=strict :

~/tmp$ uname -a
Linux ubuntu 5.4.0-37-generic #41-Ubuntu SMP Wed Jun 3 18:57:02 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
~/tmp$ cat ./test.sh
#!/usr/bin/env -S node --unhandled-rejections=strict
console.log("Hi!");
~/tmp$ ./test.sh
Hi!
~/tmp$
现在解释一下你帖子中发生的事情。
当您运行时 ./foo.sh ,它相当于运行以下命令:
/usr/bin/env "node --unhandled-rejections=strict" ./foo.sh
这是来自 man env 的摘录:
env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]
所以env由于 "node --unhandled-rejections=strict" 中的等号 (=),将“node --unhandled-rejections=strict”视为 NAME=VALUE
然后env试图运行 ./foo.sh作为现在进入无限循环的命令。

关于linux - 带有 env shebang 的脚本卡在 Linux 上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62550080/

相关文章:

linux - 清理 linux 控制台的任何输出

linux - 双重使用 bash 脚本 - 源代码和 exec 子 shell?动态返回/退出?

objective-c - 无法使用 GNUstep 在 Objective-C 上构建程序

linux - 如何使用 substr 比较替换字段

C 无限循环中的客户端/服务器失败

java - Unix:删除文件代码给出一些过程

c - ptrace(PTRACE_PEEKDATA, ...) 错误 : data dump

linux - 用于生成带有日期戳的新日志的 shell 脚本

arrays - 对 bash 脚本中的每个文件使用 exec

linux - Suricata IPS 手动阻塞/解锁 vs. snort 和 guardian