2
#!/bin/sh
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}

我对上述两件事感到困惑。

我知道 $0 是文件名,我们也使用 argv0 获取文件名。

并且 argv 是文件的参数,与 "$@" 相同,但是为什么我们要在 sritps 中同时使用这两个东西。

4

3 回答 3

5

混淆是因为$0并且${1+"$@"}不是 tcl 语法。它是 shell 语法,与 tcl 无关。

当你有这样的脚本,并从命令行运行它时,系统会认为它是一个 shell 脚本,并将开始运行每一行,就好像它是一个 shell 命令一样。在这一点上,argv0类似的变量不存在。

因为这实际上是一个 tcl 脚本。我们希望 shell 做的第一件事是停止 shell 并启动 tclsh。为此,我们执行 tclsh。此外,我们必须确保——使用 shell 语法——将参数正确地传递给 tclsh。因此,我们必须使用$0和类似的构造。一旦 tclsh 启动并且 shell 不再执行,它就会$0消失并被argv0设置。

于 2013-09-12T11:03:15.737 回答
1

$0 用于 tcl 脚本路径,${1+$@} 表示“所有参数,如果设置了第一个参数”,因此,

 exec tclsh $0 ${1+$@} 

意味着在停止 shell 之后,通过传递脚本文件(通过 $0)和其余参数(通过 ${1+$@})来执行 tclsh

当 tclsh 启动时,像 argv、argv 这样的 tcl 变量就会出现。

于 2013-09-12T11:11:45.213 回答
1
     #!/bin/sh
     # the next line restarts using tclsh \
     exec tclsh "$0" ${1+"$@"}

这种方法具有三个优点。首先,tclsh 二进制文件的位置不必硬连线到脚本中:它可以在您的 shell 搜索路径中的任何位置。其次,它绕过了前一种方法中 30 个字符的文件名限制。第三,即使 tclsh 本身是一个 shell 脚本,这种方法也可以工作(在某些系统上这样做是为了处理多个体系结构或操作系统:tclsh 脚本选择几个二进制文件之一来运行)。这三行使 sh 和 tclsh 都处理脚本,但 exec 仅由 sh 执行。sh 先处理脚本;它将第二行视为注释并执行第三行。exec 语句导致 shell 停止处理,而是启动 tclsh 以重新处理整个脚本。当 tclsh 启动时,它将所有三行视为注释,

然而,

argv : 参数变量列表

argc : 参数变量列表计数

argv0 :参数变量列表中的第一个

于 2013-09-12T10:46:27.320 回答