是否可以捕获 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 是否为空。

有没有办法捕获 FileNotFoundFolderNotFound 错误?

对于像您的示例这样的小案例,请使用 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]
}