TCL:通过SHELL环境变量检查文件是否存在(另一个)

时间:2012-09-01 06:37:33

标签: tcl

我有一个文件包含带有文件路径的行。有时路径包含SHELL环境变量,我想检查文件是否存在。 以下是我的解决方案:

set fh [open "the_file_contain_path" "r"]

while {![eof $fh]} { 
  set line [gets $fh]
  if {[regexp -- {\$\S+} $line]} {
    catch {exec /usr/local/bin/tcsh -c "echo  $line" } line
      if {![file exists $line]} {
        puts "ERROR: the file $line is not exists"
      }
  }
}

我确定没有使用

有更优雅的解决方案

/ usr / local / bin / tcsh - c

3 个答案:

答案 0 :(得分:3)

您可以在regexp命令中捕获变量名称,并在Tcl的全局env数组中进行查找。此外,您使用eof作为while条件意味着您的循环将进行一次太多的交互(请参阅http://phaseit.net/claird/comp.lang.tcl/fmm.html#eof

set fh [open "the_file_contain_path" "r"]

while {[gets $fh line] != -1} { 
  # this can handle "$FOO/bar/$BAZ"
  if {[string first {$} $line] != -1} {
    regsub -all {(\$)(\w+)} $line {\1::env(\2)} new
    set line [subst -nocommand -nobackslashes $new]
  }

  if {![file exists $line]} {
    puts "ERROR: the file $line does not exist"
  }
}

答案 1 :(得分:2)

首先,通常更容易(对于小文件,比如不超过1-2MB)读取整个文件并将split分成行而不是使用gets和{{1在eof循环中。 (while命令非常快。)

其次,要进行替换,您需要替换字符串中的位置,因此您使用split。这确实意味着您需要采用更复杂的方法来进行替换,regexp -indicesstring range可以完成一些工作。假设你正在使用Tcl 8.5 ...

string replace

答案 2 :(得分:0)

TCL程序可以使用内置的全局变量env读取环境变量。阅读该行,查找$后跟一个名称,查找$::env($name),并将其替换为变量。

如果文件由不受信任的用户提供,那么使用shell是非常糟糕的。如果他们将; rm *放入文件中该怎么办?如果你要使用shell,你应该至少使用sh或bash,而不是tcsh。