在tcl中将文件内容作为文件名本身
taking file content as file name itself in tcl
我是 运行 一个 tcl 脚本,它通过 "stdin" 将文件作为输入。问题是它将文件内容作为文件名并在 运行 时抛出错误命令行处理器上的脚本。
tcl 脚本是
#!/bin/sh
# SystemInfo_2.tcl \
exec tclsh "[=10=]" ${1+"$@"}
set traps [read stdin];
#set traps "snmp trap test"
set timetrap [clock format [clock seconds]];
set trapout [open Database_traps_event.txt a+];
set javaout [open JavaTrapOutput.txt a+];
puts $trapout $timetrap;
puts $trapout $traps;
puts $trapout "Before executing java program";
set javaprogargs "open {|java -cp mysql-connector-java-5.1.10.jar;. EventAlarmHandling \"$traps\"} r";
puts $trapout $javaprogargs;
set javaprogram [eval $javaprogargs];
puts $trapout "Execution of java is over"
while { [gets $javaprogram line] != -1 } {
puts $javaout $line;
}
close $javaprogram;
puts $trapout "After excution of java program\r\n\r\n\r\n\r\n\r\n";
close $trapout;
close $javaout;
exit;
输入文件内容为-
<UNKNOWN>
UDP: [192.168.1.19]:60572->[0.0.0.0]:0
.iso.org.dod.internet.mgmt.mib-2.system.sysUpTime.sysUpTimeInstance 1:9:58:56.61
.iso.org.dod.internet.snmpV2.snmpModules.snmpMIB.snmpMIBObjects.snmpTrap.snmpTrapOID.0 .iso.org.dod.internet.snmpV2.snmpModules.snmpMIB.snmpMIBObjects.snmpTraps.linkDown
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifIndex.1 8
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifAdminStatus.8 up
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifOperStatus.8 down
从命令行 运行 如下所示
E:\eventAlarmHandling>tclsh TclTempFile.tcl < traps.txt
couldn't read file "UNKNOWN>
UDP: [192.168.1.19]:60572->[0.0.0.0]:0
.iso.org.dod.internet.mgmt.mib-2.system.sysUpTime.sysUpTimeInstance 1:9:58:56.61
.iso.org.dod.internet.snmpV2.snmpModules.snmpMIB.snmpMIBObjects.snmpTrap.snmpTrapOID.0 .iso.org.dod.intern
et.snmpV2.snmpModules.snmpMIB.snmpMIBObjects.snmpTraps.linkDown
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifIndex.1 8
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifAdminStatus.8 up
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifOperStatus.8 down": No error
while executing
"open {|java -cp mysql-connector-java-5.1.10.jar;. EventAlarmHandling "<UNKNOWN>
UDP: [192.168.1.19]:60572->[0.0.0.0]:0
.iso.org.dod.internet.mgmt.mib..."
("eval" body line 1)
invoked from within
"eval $javaprogargs"
invoked from within
"set javaprogram [eval $javaprogargs]"
(file "TclTempFile.tcl" line 26)
在命令行中很清楚地显示 "couldn't read file UNKNOWN> ......"
所以请解释一下命令 line.I 中发生的事情是 tcl.So 的新手,希望有人能帮助我。
谢谢
您遇到了 Tcl 中管道工作方式的棘手问题之一。如果我们仔细查看 documentation ,我们会看到:
If the first character of fileName is “|
” then the remaining characters of fileName are treated as a list of arguments that describe a command pipeline to invoke, in the same style as the arguments for exec
.
这意味着您必须让第一个字符为 |
,其余字符在剥离第一个字符后,成为一个合适的列表。就您而言,您还没有。相反,你在做:
set javaprogargs "open {|java -cp mysql-connector-java-5.1.10.jar;. EventAlarmHandling \"$traps\"} r";
反正这很复杂。让我们以惯用的方式构建它:
set CPsep ";"
set classpath [list mysql-connector-java-5.1.10.jar .]
set javaprogargs [list open |[list \
java -cp [join $classpath $CPsep] EventAlarmHandling $traps]]
有助于将类路径拆分出来;它有一个 ;
字符(在 Windows 上;如果你移植到 Linux 或 OSX,你需要更改它)并且使用 [=17 更好=] 在 Tcl 中构建东西,然后 join
转换成 Java 期望的东西。
我们也不再需要任何反斜杠引用的子字符串(除了我为了保持行的简短和可读而放入的子字符串); list
命令的模式将添加所需的所有内容。请注意那里的 |[list …]
:在 Tcl 中到处都是非惯用的,除非在创建管道时 推荐的做法是相反 open
期望的做法解析。
你 运行 喜欢的另一件事是 this:
If an arg (or pair of args) has one of the forms described below then it is used by exec
to control the flow of input and output among the subprocess(es). Such arguments will not be passed to the subprocess(es).
[…]
<
fileName
The file named by fileName is opened and used as the standard input for the first command in the pipeline.
您在 $traps
中的论点以 <
开头,因此触发了此规则。
不幸的是,没有 简单的解决方法,这是管道创建代码的一个严重的、已知的、非常烦人的限制.处理这个问题的唯一已知技术是通过文件或通过子流程的标准输入来传输数据,这两种方法都需要修改子流程的实现。如果你可以让 Java 程序从 System.in
读取(无论如何这是一个好主意,所以你不会达到 Windows 的命令行长度限制!)那么你可以传递值这个:
set CPsep ";"
set classpath [list mysql-connector-java-5.1.10.jar .]
set javaprogargs [list open |[list \
java -cp [join $classpath $CPsep] EventAlarmHandling << $traps]]
只需在值之前添加一个 <<
。
我是 运行 一个 tcl 脚本,它通过 "stdin" 将文件作为输入。问题是它将文件内容作为文件名并在 运行 时抛出错误命令行处理器上的脚本。
tcl 脚本是
#!/bin/sh
# SystemInfo_2.tcl \
exec tclsh "[=10=]" ${1+"$@"}
set traps [read stdin];
#set traps "snmp trap test"
set timetrap [clock format [clock seconds]];
set trapout [open Database_traps_event.txt a+];
set javaout [open JavaTrapOutput.txt a+];
puts $trapout $timetrap;
puts $trapout $traps;
puts $trapout "Before executing java program";
set javaprogargs "open {|java -cp mysql-connector-java-5.1.10.jar;. EventAlarmHandling \"$traps\"} r";
puts $trapout $javaprogargs;
set javaprogram [eval $javaprogargs];
puts $trapout "Execution of java is over"
while { [gets $javaprogram line] != -1 } {
puts $javaout $line;
}
close $javaprogram;
puts $trapout "After excution of java program\r\n\r\n\r\n\r\n\r\n";
close $trapout;
close $javaout;
exit;
输入文件内容为-
<UNKNOWN>
UDP: [192.168.1.19]:60572->[0.0.0.0]:0
.iso.org.dod.internet.mgmt.mib-2.system.sysUpTime.sysUpTimeInstance 1:9:58:56.61
.iso.org.dod.internet.snmpV2.snmpModules.snmpMIB.snmpMIBObjects.snmpTrap.snmpTrapOID.0 .iso.org.dod.internet.snmpV2.snmpModules.snmpMIB.snmpMIBObjects.snmpTraps.linkDown
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifIndex.1 8
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifAdminStatus.8 up
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifOperStatus.8 down
从命令行 运行 如下所示
E:\eventAlarmHandling>tclsh TclTempFile.tcl < traps.txt
couldn't read file "UNKNOWN>
UDP: [192.168.1.19]:60572->[0.0.0.0]:0
.iso.org.dod.internet.mgmt.mib-2.system.sysUpTime.sysUpTimeInstance 1:9:58:56.61
.iso.org.dod.internet.snmpV2.snmpModules.snmpMIB.snmpMIBObjects.snmpTrap.snmpTrapOID.0 .iso.org.dod.intern
et.snmpV2.snmpModules.snmpMIB.snmpMIBObjects.snmpTraps.linkDown
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifIndex.1 8
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifAdminStatus.8 up
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifOperStatus.8 down": No error
while executing
"open {|java -cp mysql-connector-java-5.1.10.jar;. EventAlarmHandling "<UNKNOWN>
UDP: [192.168.1.19]:60572->[0.0.0.0]:0
.iso.org.dod.internet.mgmt.mib..."
("eval" body line 1)
invoked from within
"eval $javaprogargs"
invoked from within
"set javaprogram [eval $javaprogargs]"
(file "TclTempFile.tcl" line 26)
在命令行中很清楚地显示 "couldn't read file UNKNOWN> ......" 所以请解释一下命令 line.I 中发生的事情是 tcl.So 的新手,希望有人能帮助我。
谢谢
您遇到了 Tcl 中管道工作方式的棘手问题之一。如果我们仔细查看 documentation ,我们会看到:
If the first character of fileName is “
|
” then the remaining characters of fileName are treated as a list of arguments that describe a command pipeline to invoke, in the same style as the arguments forexec
.
这意味着您必须让第一个字符为 |
,其余字符在剥离第一个字符后,成为一个合适的列表。就您而言,您还没有。相反,你在做:
set javaprogargs "open {|java -cp mysql-connector-java-5.1.10.jar;. EventAlarmHandling \"$traps\"} r";
反正这很复杂。让我们以惯用的方式构建它:
set CPsep ";"
set classpath [list mysql-connector-java-5.1.10.jar .]
set javaprogargs [list open |[list \
java -cp [join $classpath $CPsep] EventAlarmHandling $traps]]
有助于将类路径拆分出来;它有一个 ;
字符(在 Windows 上;如果你移植到 Linux 或 OSX,你需要更改它)并且使用 [=17 更好=] 在 Tcl 中构建东西,然后 join
转换成 Java 期望的东西。
我们也不再需要任何反斜杠引用的子字符串(除了我为了保持行的简短和可读而放入的子字符串); list
命令的模式将添加所需的所有内容。请注意那里的 |[list …]
:在 Tcl 中到处都是非惯用的,除非在创建管道时 推荐的做法是相反 open
期望的做法解析。
你 运行 喜欢的另一件事是 this:
If an arg (or pair of args) has one of the forms described below then it is used by
exec
to control the flow of input and output among the subprocess(es). Such arguments will not be passed to the subprocess(es).[…]
<
fileName
The file named by fileName is opened and used as the standard input for the first command in the pipeline.
您在 $traps
中的论点以 <
开头,因此触发了此规则。
不幸的是,没有 简单的解决方法,这是管道创建代码的一个严重的、已知的、非常烦人的限制.处理这个问题的唯一已知技术是通过文件或通过子流程的标准输入来传输数据,这两种方法都需要修改子流程的实现。如果你可以让 Java 程序从 System.in
读取(无论如何这是一个好主意,所以你不会达到 Windows 的命令行长度限制!)那么你可以传递值这个:
set CPsep ";"
set classpath [list mysql-connector-java-5.1.10.jar .]
set javaprogargs [list open |[list \
java -cp [join $classpath $CPsep] EventAlarmHandling << $traps]]
只需在值之前添加一个 <<
。