#!/bin/sh
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
我对上述两件事感到困惑。
我发现$ 0是文件名,我们使用argv0获取文件名。
而argv是该文件的参数,与“$ @”相同,但我们为什么要在我们的文本中使用这两个东西。
答案 0 :(得分:4)
混淆是因为$0
和${1+"$@"}
不是tcl语法。它是shell语法,与tcl无关。
当你有这样的脚本,并且从命令行运行它时,系统认为它是一个shell脚本,并且将开始像运行shell命令一样运行每一行。此时,argv0
和类似变量不存在。
因为这实际上是一个tcl脚本。我们希望shell做的第一件事是停止shell并启动tclsh。为此,我们执行tclsh。此外,我们必须确保 - 使用shell语法 - 将参数正确传递给tclsh。因此,我们必须使用$0
和类似的结构。一旦tclsh启动并且shell不再执行,$0
就会消失并设置argv0
。
答案 1 :(得分: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:首先在参数变量列表中
答案 2 :(得分:0)
$ 0表示tcl脚本路径,$ {1 + $ @}表示“所有参数,如果设置了第一个参数” 因此,
exec tclsh $0 ${1+$@}
表示停止shell后,通过传递脚本文件(通过$ 0)和其他参数(通过$ {1 + $ @})执行tclsh
当tclsh启动时,像argv,argv这样的tcl变量将会出现。