Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Weird 'cd' behavior

38 views
Skip to first unread message

tcl...@gmail.com

unread,
Dec 5, 2017, 11:22:43 AM12/5/17
to
Hello,

I have something strange happening with a script that goes through a directory structure.

To test it I created a directory call "Test" and put there several empty directories "A", "B", "C", "CA", "CB" and "CC".

I open tclsh8.6 in the test directory and run the following script:

[root@Backup Test]# tclsh8.6
% foreach dir [glob */] { puts "$dir" ; cd "$dir"; puts [pwd] ; cd ..}
CC/
/home/Samba/c/Backup/User1/GEO/Coveris/Test/CC
CA/
/home/Samba/c/Backup/User1/GEO/Coveris/Test/CA
B/
/home/Samba/c/Backup/User1/GEO/Coveris/TestB
CB/
/home/Samba/c/Backup/User1/GEO/Coveris/CB
A/
/home/Samba/c/Backup/User1/GEO/CoverisA
C/
/home/Samba/c/Backup/User1/GEOC

As you can see, when the name of the subdirectory is a single letter, the 'cd' command gets confused and tries to enter a directory that doesn't exist, but it doesn't return an error an 'pwd' thinks it is in the nonexisting dir.

But it only happens when I run the script, if I enter the command one by one in in tclsh it works.

After trying for a couple of hours to find the bug in my original script, I tried using Tcl 8.4, and it works fine:

[root@Backup Test]# tclsh8.4
% foreach dir [glob */] { puts "$dir" ; cd "$dir"; puts [pwd] ; cd ..}
CC/
/home/Samba/c/Backup/User1/GEO/Coveris/Test/CC
CA/
/home/Samba/c/Backup/User1/GEO/Coveris/Test/CA
B/
/home/Samba/c/Backup/User1/GEO/Coveris/Test/B
CB/
/home/Samba/c/Backup/User1/GEO/Coveris/Test/CB
A/
/home/Samba/c/Backup/User1/GEO/Coveris/Test/A
C/
/home/Samba/c/Backup/User1/GEO/Coveris/Test/C
%


Any idea what could possible be wrong?

Thanks,
Andrés García

Gerald Lester

unread,
Dec 5, 2017, 11:46:35 AM12/5/17
to
Not sure exactly what is wrong or why, but the following does what you want:

foreach dir [glob -types d *] {
puts "in [pwd] changing to {$dir}";
cd $dir;
puts "\t now in [pwd]";
cd ..
}


--
+----------------------------------------------------------------------+
| Gerald W. Lester, President, KNG Consulting LLC |
| Email: Gerald...@kng-consulting.net |
+----------------------------------------------------------------------+

Don Porter

unread,
Dec 5, 2017, 11:50:53 AM12/5/17
to
On 12/05/2017 11:22 AM, tcl...@gmail.com wrote:
> I created a directory call "Test" and put there several empty directories "A", "B", "C", "CA", "CB" and "CC".

> [root@Backup Test]# tclsh8.6
> % foreach dir [glob */] { puts "$dir" ; cd "$dir"; puts [pwd] ; cd ..}
> CC/
> /home/Samba/c/Backup/User1/GEO/Coveris/Test/CC
> CA/
> /home/Samba/c/Backup/User1/GEO/Coveris/Test/CA
> B/
> /home/Samba/c/Backup/User1/GEO/Coveris/TestB

...

> Any idea what could possible be wrong?

It appears you've detected a bug no one else has noticed in more than
a decade.

Until it is fixed, the workaround is this:

foreach dir [glob -types d *] { puts "$dir" ; cd "$dir"; puts [pwd] ; cd ..}

--
| Don Porter Applied and Computational Mathematics Division |
| donald...@nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|

Brad Lanam

unread,
Dec 5, 2017, 11:52:02 AM12/5/17
to
On Tuesday, December 5, 2017 at 8:22:43 AM UTC-8, tcl...@gmail.com wrote:
> Hello,
>
> I have something strange happening with a script that goes through a directory structure.
>
> To test it I created a directory call "Test" and put there several empty directories "A", "B", "C", "CA", "CB" and "CC".
>
> I open tclsh8.6 in the test directory and run the following script:
>
> [root@Backup Test]# tclsh8.6
> % foreach dir [glob */] { puts "$dir" ; cd "$dir"; puts [pwd] ; cd ..}
> CC/
> /home/Samba/c/Backup/User1/GEO/Coveris/Test/CC
> CA/
> /home/Samba/c/Backup/User1/GEO/Coveris/Test/CA
> B/
> /home/Samba/c/Backup/User1/GEO/Coveris/TestB
> CB/
> /home/Samba/c/Backup/User1/GEO/Coveris/CB
> A/
> /home/Samba/c/Backup/User1/GEO/CoverisA
> C/
> /home/Samba/c/Backup/User1/GEOC
>
> As you can see, when the name of the subdirectory is a single letter, the 'cd' command gets confused and tries to enter a directory that doesn't exist, but it doesn't return an error an 'pwd' thinks it is in the nonexisting dir.
>
> But it only happens when I run the script, if I enter the command one by one in in tclsh it works.

I was able to reproduce the bug using the supplied script.
The following two scripts do _not_ reproduce the bug.

proc x {} { cd C; puts [pwd]; cd .. }

proc x {} { cd C/; puts [pwd]; cd .. }

Also, after the bug occurs, one of the cd/pwd command stops working properly -- either cd doesn't work or pwd does not report properly.

This works:
proc x { d } { puts $d; cd $d; puts [pwd]; cd .. }
foreach dd [list A B C CA CB CC] { x $dd }

So it appears that 'glob' is trashing something. But not always.
Setting ::tcl_interactive to 0 and the interactive commands still work.

Brad Lanam

unread,
Dec 5, 2017, 11:58:14 AM12/5/17
to
On Tuesday, December 5, 2017 at 8:50:53 AM UTC-8, Don Porter wrote:
> On 12/05/2017 11:22 AM, tclcurl wrote:
> > I created a directory call "Test" and put there several empty directories "A", "B", "C", "CA", "CB" and "CC".
>
> > [root@Backup Test]# tclsh8.6
> > % foreach dir [glob */] { puts "$dir" ; cd "$dir"; puts [pwd] ; cd ..}
> > CC/
> > /home/Samba/c/Backup/User1/GEO/Coveris/Test/CC
> > CA/
> > /home/Samba/c/Backup/User1/GEO/Coveris/Test/CA
> > B/
> > /home/Samba/c/Backup/User1/GEO/Coveris/TestB
>
> ...
>
> > Any idea what could possible be wrong?
>
> It appears you've detected a bug no one else has noticed in more than
> a decade.
>
> Until it is fixed, the workaround is this:
>
> foreach dir [glob -types d *] { puts "$dir" ; cd "$dir"; puts [pwd] ; cd ..}
>
> --
> | Don Porter Applied and Computational Mathematics Division |


And,
foreach dir [glob *] { puts "$dir" ; cd "$dir"; puts [pwd] ; cd ..}
without the trailing slash also works.

Andreas Leitgeb

unread,
Dec 5, 2017, 3:09:03 PM12/5/17
to
Brad Lanam <brad....@gmail.com> wrote:
> On Tuesday, December 5, 2017 at 8:22:43 AM UTC-8, tcl...@gmail.com wrote:
>> I have something strange happening with a script that goes through a directory structure.
>> To test it I created a directory call "Test" and put there several empty directories "A", "B", "C", "CA", "CB" and "CC".
>> I open tclsh8.6 in the test directory and run the following script:
>> [root@Backup Test]# tclsh8.6
>> % foreach dir [glob */] { puts "$dir" ; cd "$dir"; puts [pwd] ; cd ..}
> Also, after the bug occurs, one of the cd/pwd command stops working properly
> either cd doesn't work or pwd does not report properly.

After the bug occurs, pwd reports some super-super-super-directory,
and glob * shows the contents of that s.-s.-s.-dir.

But then, [exec pwd] still reports the original directory where I started from
and [exec ls] shows the mentioned test-subdirs "A", "B", "C", "CA", "CB" and "CC".

At this point, even "cd [exec pwd]" does nothing (and in particular
not repair the internal state), while cd'ing to a super-dir of the
original dir does repair the internal mess.

fwiw & thanks to OP for reporting it!

I'm glad that OP tried that way and thus found this bug, but in general,
I'd recommend saving the [pwd] and always cd to the saved dir, rather than
relying on ".." - there are traps that may catch you, like symlinks, or
directories being moved while you're inside them...

0 new messages