通过bash heredoc将参数传递给tclsh

时间:2017-11-23 00:35:23

标签: bash heredoc tclsh

我有以下测试用例:

#!/bin/bash
tclsh <<EOF
puts "argv=$argv"
EOF

如何将参数传递给tclsh?参数必须在之后文件(根据tclsh的手册页)

SYNOPSIS
    tclsh ?-encoding name? ?fileName arg arg ...?

更新

首先,我将使用bash命令标志并使用它们为tclsh创建参数:

tclarg1="....."
tclarg2="....."

然后我将使用tcl:

获得字符串变量
SCRIPT='
    proc test{arg1 arg2} {
        some tcl commands
    }
    test ???? ????
'

最后我执行该字符串:

tclsh <<-HERE
${POPUPSCRIPT}
HERE

我如何通过&#34; tclarg1&#34;和&#34; tclarg2&#34;到tcl脚本?

字符串可以来自其他来源(通过获取另一个文件),bash脚本也可以从多个位置/函数执行该字符串。

3 个答案:

答案 0 :(得分:0)

#!/bin/bash
tclsh <<EOF
puts "argv=$@"
EOF

答案 1 :(得分:0)

这是一个棘手的小问题,因为heredocs对它们在命令行中的位置很挑剔。另外,它们最终以文件描述符的形式传递给命令,因此需要一些技巧。

#!/bin/bash

# Get the script into a variable. Note the backticks and the single quotes around EOF
script=`cat <<'EOF'
puts "argv=$argv"
EOF`

# Supply the script to tclsh as a file descriptor in the right place in the command line
tclsh <(echo $script) "$@"

这似乎是对的。

bash$ /tmp/testArgPassing.sh a 'b c' d
argv=a {b c} d

但是,我肯定会始终使用单独的.tcl文件,以免发生这种情况。在Tcl中,参数操纵至少与在Bash中一样容易,并且这样做还使各种编辑器也可以提供合理的语法高亮显示。

借助tclsh,很容易在PATH上找到正确的/usr/bin/env

#!/usr/bin/env tclsh
puts "argv=$argv"

答案 2 :(得分:0)

此处文档发送到程序的标准输入,因此您的命令:

tclsh <<EOF
puts "argv=$argv"
EOF

不带任何参数(甚至没有文件名)调用tclsh,并将puts "argv="写入tclsh的标准输入。 (请注意,$argv是由Bash处理的,因此tclsh永远不会看到它。要解决该问题,您需要编写<<'EOF'而不是<<EOF。)

因此,为了将参数传递给tclsh脚本,您需要向tclsh传递文件名参数,以便您的参数可以在该文件名参数之后。

由于将heredocs发送到程序的标准输入,因此要使用的文件名仅为/dev/stdin

tclsh /dev/stdin "$tclarg1" "$tclarg2" <<'EOF'
puts "argv=$argv"
EOF

请注意,使用这种方法,tclsh将不再在脚本开始时隐式运行.tclshrc(因为它仅在默认时才从标准输入读取)而不给出任何参数)。如果您需要.tclshrc中的任何内容,则需要明确source

tclsh /dev/stdin "$tclarg1" "$tclarg2" <<'EOF'
source ~/.tclshrc
puts "argv=$argv"
EOF