内核如何执行事情
简化(有点),POSIX 系统中的内核有两种方式知道如何执行程序。一,如果程序是内核理解的二进制格式(例如ELF),内核可以“直接”执行它(更多细节超出范围)。如果程序是以shebang开头的文本文件,比如
#!/usr/bin/somebinary -arg
或者你有什么,内核实际上执行命令就好像它被指示执行:
/usr/bin/somebinary -arg "$0"
其中$0 是您刚刚尝试执行的脚本文件的名称。 (所以你可以立即知道为什么这么多脚本语言使用# 作为注释启动器——这意味着它们不必将shebang 视为特殊。)
PATH 和 env 命令
内核不会查看 PATH 环境变量来确定您正在谈论的可执行文件,因此如果您将 python 脚本分发到可能安装了多个 python 版本的系统,您不能保证会有做一个
#!/usr/bin/python
然而,
env 是POSIX,所以你可以指望它存在,it 会在 PATH 中查找 python。因此,
#!/usr/bin/env python
将使用 PATH 中找到的第一个 python 执行脚本。
BASH、SH 和调用的特殊含义
一些程序对于如何调用它们有特殊的语义。特别是,在许多系统上,/bin/sh 是指向另一个 shell 的符号链接,例如 /bin/bash。虽然 bash 不包含 sh 的完美 POSIXLY_STRICT 实现,但当它以 /bin/sh 调用时,它比以 plain-old-bash 调用时要更严格。
MySQL 和 arg 限制
shebang 行有长度限制,从技术上讲,它只能支持一个参数,所以 mysql 有点棘手——你不能指望将用户名和数据库名称传递给 mysql 脚本。
#!/usr/bin/env mysql
use mydb;
select * from mytbl;
将失败,因为内核将尝试mysql "$0"。即使您在.my.cnf 文件中有您的凭据,mysql 本身也会尝试将“$0”视为数据库名称。同样:
#!/usr/bin/mysql -e
use mydb;
select * from mytbl;
将再次失败,因为“$0”不是表名(您希望如此)。
以这种方式直接执行 mysql 脚本似乎没有合适的语法。最好的办法是将 sql 命令直接通过管道传输到 mysql:
mysql < my_sql_commands