在 shell 脚本中,可以在 shebang() 行指定语言解释器#!
。据我所知,建议使用,#!/usr/bin/env bash
因为env
始终位于/usr/bin
目录中,而 的位置bash
可能因系统而异。但是,如果bash
直接使用实用程序启动/bin/bash
或通过实用程序启动,是否有任何技术差异env
?另外,如果我没有为 指定任何变量env
,则bash
在未修改的环境中启动,我是否正确?
答案1
从某种意义上说, usingenv
可以被认为是“可移植的”,因为它的路径bash
是不相关的(/bin/bash
、/usr/bin/bash
、/usr/local/bin/bash
、~/bin/bash
或任何路径),因为它是在环境中指定的。通过这种方式,脚本作者可以使他的脚本更容易在许多不同的系统上运行。
从另一种意义上说,使用env
findbash
或任何其他 shell 或命令解释器都被视为安全风险,因为可能使用未知的二进制文件(恶意软件)来执行脚本。在这些环境中,有时根据管理策略,路径是使用完整路径显式指定的:#!/bin/bash
。
一般来说,env
除非您知道您正在这些仔细检查风险细节的环境之一中进行写作,否则请使用。
当 Ubuntu 第一次开始使用dash
2011 年的某个时候时,许多脚本都被这个操作破坏了。 askubuntu.com 上对此进行了讨论。大多数脚本都是#!/bin/sh
通过链接编写的/bin/bash
。共识是:剧本作者负责指定解释器。因此,如果您的脚本应始终使用 BASH 调用,请从环境中指定它。这使您不必猜测路径,该路径在各种 Unix/Linux 系统上是不同的。此外,如果明天/bin/sh
成为到其他 shell(如/bin/newsh
.
另一个区别是该env
方法不允许将参数传递给解释器。
答案2
除了使用速度稍慢之外/usr/bin/env
,如果您启动一个这样的程序,那么没有什么区别。 (除非 /bin/bash
不存在但bash
位于路径中的某个位置)
env
可以修改调用命令的环境,但只能在env
从命令行启动时使用,在 shebang 行(取决于操作系统)中无法指定选项。
这来源env
相当小,因此如果您熟悉 C,您可以验证它在做什么。Sinceexecvp
用于调用要执行的程序。env
如果您检查进程树,甚至不会有父进程。