From: j.lewandowski on
I have a problem with file command to detect broken symbolic link on
unix.
example:
I am creating broken symbolic link in bash
# ln -s /etc/hostss hostss
now in tcl
% file exists hostss
0
% file copy /etc/hosts hostss
error copying "/etc/hosts" to "hostss": file already exists

My question is: file hostss exists or not? :) :)

Is any elegant method to detect broken symbolic links in tcl?

From: Eric Hassold on
j.lewandowski(a)gazeta.pl a �crit :
> I have a problem with file command to detect broken symbolic link on
> unix.
> example:
> I am creating broken symbolic link in bash
> # ln -s /etc/hostss hostss
> now in tcl
> % file exists hostss
> 0
> % file copy /etc/hosts hostss
> error copying "/etc/hosts" to "hostss": file already exists
>
> My question is: file hostss exists or not? :) :)
>
> Is any elegant method to detect broken symbolic links in tcl?
>

Hi,

% file type hostss
link
% file exists hosts
0
% file readlink hosts
/etc/hostss

So, to detect a broken link, you may use:

proc brokenlink {f} {
if {![catch {file type $f} ftype]} {
if {$ftype eq "link" && ![file exists $f]} {
return 1
}
}

return 0
}

Is it elegant? I don't know.

Eric
From: Glenn Jackman on
At 2008-06-24 08:26AM, "Eric Hassold" wrote:
> So, to detect a broken link, you may use:

I can't resist commenting on this proc.

> proc brokenlink {f} {
> if {![catch {file type $f} ftype]} {

[file type] will only throw an error if $f does not exist (as far as I
know). I think that's something the caller would want to know, so I'd
let that error propagate up.

> if {$ftype eq "link" && ![file exists $f]} {

You probably meant to use [file exists [file readlink $f]] there

> return 1
> }
> }
>
> return 0
> }


How about:

proc is_broken {linkname} {
return [expr { ! [file exists [file readlink $linkname]]]
}

It will error if $linkname does not exist or is not a link file, so:

set rc [catch {is_broken $filename} result]
if {$rc == 0 && $result} {
puts "$filename is a broken link"
} elseif {$rc == 0} {
puts "link $filename is OK"
} else {
puts "not a link: $result"
}

--
Glenn Jackman
Write a wise saying and your name will live forever. -- Anonymous
From: Larry W. Virden on
On Jun 24, 9:52 am, Glenn Jackman <gle...(a)ncf.ca> wrote:

>
> How about:
>
>     proc is_broken {linkname} {
>         return [expr { ! [file exists [file readlink $linkname]]]

Change this return line instead to be

return [expr { ! [file exists [file readlink $linkname]] } ]

>     }
>
> It will error if $linkname does not exist or is not a link file, so:
>
>     set rc [catch {is_broken $filename} result]
>     if {$rc == 0 && $result} {
>         puts "$filename is a broken link"
>     } elseif {$rc == 0} {
>         puts "link $filename is OK"
>     } else {
>         puts "not a link: $result"
>     }
>

If filename points to a string that does not represent a file, you
get:
not a link: could not readlink "/tmp/Wow!": no such file or directory
If filename contains the pathname of an existing link to a non-
existing file, you get:
/tmp/stillnot is a broken link
If filename contains the pathname of an existing link to an existing
file, you get:
link /tmp/notthere is OK
From: Glenn Jackman on
At 2008-06-24 10:02AM, "Larry W. Virden" wrote:
> On Jun 24, 9:52�am, Glenn Jackman <gle...(a)ncf.ca> wrote:
> > � � proc is_broken {linkname} {
> > � � � � return [expr { ! [file exists [file readlink $linkname]]]
>
> Change this return line instead to be
>
> return [expr { ! [file exists [file readlink $linkname]] } ]

Oops, yes.

[...]
> If filename contains the pathname of an existing link to an existing
> file, you get:
> link /tmp/notthere is OK

I take it you mean
ln -s notthere link1
ln -s link1 link2

then [is_broken link2] returns true. Hmm, better make it recursive:

proc is_broken {linkname} {
set linked [file readlink $linkname]
if { ! [file exists $linked]} {
return true ;# a broken link
}
if {[file type $linked] ne "link"} {
return false ;# this link points to an existing file
}
return [is_broken $linked] ;# follow the white rabbit
}



--
Glenn Jackman
Write a wise saying and your name will live forever. -- Anonymous