是否可以捕获 glob 的错误输出?
Is it possible to capture the error output of glob?
假设我在 try/trap/finally
中包含以下 glob
命令:
proc generateSubmissionFolder {cover_letter_resume submission_path} {
set submission_parent [file dirname $submission_path]
set latest_submission_folder [lindex [lsort [glob -directory $submission_parent -type d *]] end]
set latest_submission_file [lindex [glob -directory $latest_submission_folder *[file extension $cover_letter_resume]] end]
createSubmissionFolder $latest_submission_file $submission_path
}
proc createSubmissionFolder {source destination} {
puts "Creating $destination folder."
file mkdir $destination
puts "Copying $source to $destination"
file copy $source $destination
}
try {
# I gathered user input and stored them in the variables $company_name and $position.
set submission_path [file join $company_name $position $yearmonthday]
if {[file exists [file dirname $submission_path]]} {
generateSubmissionFolder $coverletterresume $submission_path
} else {
createSubmissionFolder $coverletterresume $submission_path
}
} trap {Value Empty} {errormessage} {
puts "$errormessage"
} finally {
puts "$argv0 exiting."
}
如果找不到文件夹,我想提供一条人类可读的错误消息,但我不确定要捕获什么错误。根据 我之前的问题:
Tcl doesn't have a pre-defined hierarchy of exceptions.
我尝试的唯一解决方法是使用 -nocomplain
开关,然后检查 latest_submission_folder
是否为空。
有没有办法捕获 FileNotFound
或 FolderNotFound
错误?
对于像您的示例这样的小案例,请使用 on error
处理程序,而不是 trap
。或者使用 catch
而不是 try
.
示例 tclsh
会话:
% try { glob *.bar } on error {what} { puts "Ooops: $what" }
Ooops: no files matched glob pattern "*.bar"
% if {[catch { glob *.bar } result] == 1} { puts "Ooops: $result" }
Ooops: no files matched glob pattern "*.bar"
或者如果你确实想使用 trap
因为你还想处理来自更复杂代码的一堆其他可能的特定错误,glob
在失败时引发 TCL OPERATION GLOB NOMATCH
:
% try { glob *.bar } trap {TCL OPERATION GLOB NOMATCH} {msg} { puts "Ooops: $msg" }
Ooops: no files matched glob pattern "*.bar"
对于任何给定命令的特定错误,您可以通过 trap
发现使用什么,例如:
% catch { glob *.bar } result errdict
1
% dict get $errdict -errorcode
TCL OPERATION GLOB NOMATCH
在这种 特定情况下, glob
有一个有用的选项:-nocomplain
。它关闭了不匹配的错误——这只是真正用于交互使用的——因为很多用例可以很好地处理一个空的返回列表。 (由于历史原因,它是这样的,并且以这种方式维护,所以我们不会破坏使用它的大量现有脚本。随着语言的发展,它并不太糟糕。)
set latest_submission_folder [glob -directory $submission_parent -type d *]
if {![llength $latest_submission_folder]} {
# Make your own handling right here. Whatever you want.
puts "I didn't find a directory inside $submission_parent"
} elseif {[llength $latest_submission_folder] > 1} {
# Many subdirectories found. Is this an error given your single-thing var name?
} else {
# Strip a layer of list; good idea in case directory name has a space in it!
set latest_submission_folder [lindex $latest_submission_folder 0]
}
假设我在 try/trap/finally
中包含以下 glob
命令:
proc generateSubmissionFolder {cover_letter_resume submission_path} {
set submission_parent [file dirname $submission_path]
set latest_submission_folder [lindex [lsort [glob -directory $submission_parent -type d *]] end]
set latest_submission_file [lindex [glob -directory $latest_submission_folder *[file extension $cover_letter_resume]] end]
createSubmissionFolder $latest_submission_file $submission_path
}
proc createSubmissionFolder {source destination} {
puts "Creating $destination folder."
file mkdir $destination
puts "Copying $source to $destination"
file copy $source $destination
}
try {
# I gathered user input and stored them in the variables $company_name and $position.
set submission_path [file join $company_name $position $yearmonthday]
if {[file exists [file dirname $submission_path]]} {
generateSubmissionFolder $coverletterresume $submission_path
} else {
createSubmissionFolder $coverletterresume $submission_path
}
} trap {Value Empty} {errormessage} {
puts "$errormessage"
} finally {
puts "$argv0 exiting."
}
如果找不到文件夹,我想提供一条人类可读的错误消息,但我不确定要捕获什么错误。根据
Tcl doesn't have a pre-defined hierarchy of exceptions.
我尝试的唯一解决方法是使用 -nocomplain
开关,然后检查 latest_submission_folder
是否为空。
有没有办法捕获 FileNotFound
或 FolderNotFound
错误?
对于像您的示例这样的小案例,请使用 on error
处理程序,而不是 trap
。或者使用 catch
而不是 try
.
示例 tclsh
会话:
% try { glob *.bar } on error {what} { puts "Ooops: $what" }
Ooops: no files matched glob pattern "*.bar"
% if {[catch { glob *.bar } result] == 1} { puts "Ooops: $result" }
Ooops: no files matched glob pattern "*.bar"
或者如果你确实想使用 trap
因为你还想处理来自更复杂代码的一堆其他可能的特定错误,glob
在失败时引发 TCL OPERATION GLOB NOMATCH
:
% try { glob *.bar } trap {TCL OPERATION GLOB NOMATCH} {msg} { puts "Ooops: $msg" }
Ooops: no files matched glob pattern "*.bar"
对于任何给定命令的特定错误,您可以通过 trap
发现使用什么,例如:
% catch { glob *.bar } result errdict
1
% dict get $errdict -errorcode
TCL OPERATION GLOB NOMATCH
在这种 特定情况下, glob
有一个有用的选项:-nocomplain
。它关闭了不匹配的错误——这只是真正用于交互使用的——因为很多用例可以很好地处理一个空的返回列表。 (由于历史原因,它是这样的,并且以这种方式维护,所以我们不会破坏使用它的大量现有脚本。随着语言的发展,它并不太糟糕。)
set latest_submission_folder [glob -directory $submission_parent -type d *]
if {![llength $latest_submission_folder]} {
# Make your own handling right here. Whatever you want.
puts "I didn't find a directory inside $submission_parent"
} elseif {[llength $latest_submission_folder] > 1} {
# Many subdirectories found. Is this an error given your single-thing var name?
} else {
# Strip a layer of list; good idea in case directory name has a space in it!
set latest_submission_folder [lindex $latest_submission_folder 0]
}