#!/bin/sh
# A Tcl comment, whose contents don't matter \
exec tclsh "$0" "$@"
我们为什么要调用壳在这里(#!/ bin / sh的)。
我们可以直接调用tclsh的(#!/ usr / sbin目录/ tclsh的)。 让我们假定tclsh时,在sbin目录directoey。
为什么我们首先调用外壳,并再次壳内我们调用tclsh的解释。
为什么人们喜欢使用这些(#!/ bin / sh的,EXEC tclsh的 “$ 0” “$ @”)。 我们不能执行tclsh的照片直接?
由于种种原因,在某些系统上,可以牢固地锁定了哪些可执行可以在认领线运行。 换句话说,它可能会拒绝在不运行任何/bin
。 或者,也许,如果你的管理员特别残暴,他们可能会试图迫使大家使用zsh
:-)
其次,这将运行tclsh
根据当前路径设置。 如果你想不同的用户有不同版本的TCL的运行是非常重要的。 否则,你必须给的家当线上的绝对路径,这可能是在不同的系统不同(尽管/usr/bin/env
还可以采取照顾)。
这也是方便测试与较新版本的脚本tclsh
承诺之前。 例如,你可以在8.5 tclsh的当前最新的Debian(7.1),而在构建它测试TCL 8.6 $HOME/staging/tcl86
和改变你的路径,以便目录之前出现usr/bin
。
在我的系统(这是锁定到我的规格,但没有进一步的),脚本:
#!/usr/bin/env tclsh
puts $tcl_version
工作得很好,输出:
8.5
如此做脚本:
#!/usr/bin/tclsh
puts $tcl_version
虽然,如前所述,它是依赖于系统版本tclsh
,而不是我的路径上的第一个。
而且,是的,你可以在参数就好了,按照下面的全文:
pax> cat qq.tcsh
#!/usr/bin/tclsh
puts $argc
puts $argv
pax> qq.tcsh my name is pax
4
my name is pax
当你有这样一个脚本,你在命令行中运行它,系统认为它是一个shell脚本,并开始运行的每一行,就好像它是一个shell命令。
$ 0和$ @是壳变量.. $ 0为TCL脚本路径和$ {1 + $ @}表示“所有的参数,如果第一参数设置”,因此,
exec tclsh $0 ${1+$@}
装置停止后壳,通过使脚本文件(通过$ 0)执行tclsh的休息参数(经由$ {1 + $ @})
当tclsh的开始,像TCL的argv变量,argv的将进入画面。
原因二本上线一开始是解决32个字符的行限制的特殊家当线。
#!/bin/sh
# A Tcl comment, whose contents don't matter \
exec /some/very/long/path/to/find/a/tcl/executable/path/tclsh "$0" "$@"
主要历史原因是,作为@Shawn提到的,一些老Unix系统不能处理长的家当。
第二个原因是在系统布局方面的便携性。 你举的例子#!/usr/sbin/tclsh
是一个很好的例子,因为它不会在我的机器上工作。 没有tclsh
在/usr/sbin
,我的是在~/.nix-profile/bin/tclsh
。 它也将不适合,有一个用户tclsh
在/usr/sbin
但我们更希望的另一个版本tclsh
是他们在早前PATH
。
有人可能会认为,我们可以只使用#!tclsh
,这将解决这两个问题,但也有许多系统今天仍然需要的绝对路径。 但有一个非官方的官方便携式解决方案:
#!/usr/bin/env tclsh
这适用于一般的GNU / Linux发行版,在Cygwin / msys2在Windows中,并因为过去二十年回各种Unix系统的。 它是如家当tklib
用途: https://github.com/tcltk/tklib/commit/4ea165c5d8b126185e4bbb341e53289a0efc931d
这招是如此普遍和预期的工作,不只是TCL但对于其他的东西太多,即使NixOS,否则有一个空/usr/bin
,有一个/usr/bin/env
。
欲了解更多关于/usr/bin/env
和口译一般,看到https://askubuntu.com/questions/88314/what-type-of-path-in-shebang-is-more-preferable 。
欲了解更多关于shebangs和TCL,见https://wiki.tcl-lang.org/page/exec+magic 。