TCL:通过SHELL环境变量检查文件存在性(另一个)
我有一个文件,其中包含文件路径的行。有时路径包含SHELL环境变量,我想检查文件是否存在。 以下是我的解决方案:TCL:通过SHELL环境变量检查文件存在性(另一个),tcl,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 {!
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-cTCL程序可以使用内置的全局变量
env
读取环境变量。阅读该行,查找$
,后跟名称,查找$::env($name)
,然后用它替换变量
如果文件是由不受信任的用户提供的,那么使用shell进行此操作是非常糟糕的。如果他们把
;文件中的rm*
?如果要使用shell,至少应该使用sh或bash,而不是tcsh。TCL程序可以使用内置全局变量env
读取环境变量。阅读该行,查找$
,后跟名称,查找$::env($name)
,然后用它替换变量
如果文件是由不受信任的用户提供的,那么使用shell进行此操作是非常糟糕的。如果他们把
;文件中的rm*
?如果要使用shell,至少应该使用sh或bash,而不是tcsh。您可以在regexp命令中捕获变量名,并在Tcl的globalenv
数组中进行查找。此外,将eof
用作while条件意味着您的循环将重复一次(请参阅)
您可以在regexp命令中捕获变量名,并在Tcl的global
env
数组中进行查找。此外,将eof
用作while条件意味着您的循环将重复一次(请参阅)
首先,在
while
循环中使用get
和eof
而不是get
时,通常更容易(对于小文件,比如不超过1–2MB的文件)读取整个文件并将其拆分为行。(split命令的速度非常快。)
其次,要进行替换,需要在字符串中找到要替换的位置,因此使用regexp-index
。这确实意味着您需要采取更复杂的方法来进行替换,使用string range
和string replace
来完成部分工作。假设您使用的是Tcl 8.5
set fh [open "the_file_contain_path" "r"]
foreach line [split [read $fh] "\n"] {
# Find a replacement while there are any to do
while {[regexp -indices {\$(\w+)} $line matchRange nameRange]} {
# Get what to replace with (without any errors, just like tcsh)
set replacement {}
catch {set replacement $::env([string range $line {*}$nameRange])}
# Do the replacement
set line [string replace $line {*}$matchRange $replacement]
}
# Your test on the result
if {![file exists $line]} {
puts "ERROR: the file $line is not exists"
}
}
首先,在
while
循环中使用get
和eof
而不是get
时,通常更容易(对于小文件,比如不超过1–2MB的文件)读取整个文件并将其拆分为行。(split命令的速度非常快。)
其次,要进行替换,需要在字符串中找到要替换的位置,因此使用regexp-index
。这确实意味着您需要采取更复杂的方法来进行替换,使用string range
和string replace
来完成部分工作。假设您使用的是Tcl 8.5
set fh [open "the_file_contain_path" "r"]
foreach line [split [read $fh] "\n"] {
# Find a replacement while there are any to do
while {[regexp -indices {\$(\w+)} $line matchRange nameRange]} {
# Get what to replace with (without any errors, just like tcsh)
set replacement {}
catch {set replacement $::env([string range $line {*}$nameRange])}
# Do the replacement
set line [string replace $line {*}$matchRange $replacement]
}
# Your test on the result
if {![file exists $line]} {
puts "ERROR: the file $line is not exists"
}
}
这不完全是一回事;它不能很好地处理
$FOO/bar
。您好,Glenn,您更新的解决方案工作正常。非常感谢。那不是一回事;它不能很好地处理$FOO/bar
。您好,Glenn,您更新的解决方案工作正常。谢谢。