5

I have a strange problem on my Linux Mint machine (with solid-state drive if that matters). Somehow the machine (on multiple occasions) gets different files, and different content for the same file, if I do "ls $PWD" instead of "ls ." or just "ls". That means I can write the file into the present working directory and pick up something different copying it from another directory.

It's not $PWD set to the wrong thing, I can hand-type the directory name.

I've checked this pretty carefully, but it does come and go. That makes it hard to make and to test production scripts and code.

adam@RADIUM:/home/adam/cd2/adam_dev/rsim ==> ls .
ClearPrice.cme Makefile.win data gfiles rsim5.tmp src zlib
ClearPrice.src ReadMe.txt err include rsimdone.txt tools
Makefile build g2f out scripts vs2013
adam@RADIUM:/home/adam/cd2/adam_dev/rsim ==>
adam@RADIUM:/home/adam/cd2/adam_dev/rsim ==> echo $PWD
/home/adam/cd2/adam_dev/rsim
adam@RADIUM:/home/adam/cd2/adam_dev/rsim ==> ls $PWD
ClearPrice.cmd Makefile.win err include scripts vs2013
ClearPrice.src ReadMe.txt g2f out src zlib Makefile build
gfiles rsimdone.txt tools
adam@RADIUM:/home/adam/cd2/adam_dev/rsim ==>
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • in addition to the answers below: it can also happen if the PWD is a symlink. for ex: if `/path/of/symlink -> /actual/pointed/directory` : when you do `cd /path/to/symlink` your PWD is `/path/of/symlink`. Therefore `ls -l "$PWD"` will show the link itself, not its content. `ls -l "$PWD/"` will show its content. there are other caveats with symlinks... (note: `cd -P /path/to/symlink` (or even : `cd -P .` once you are in it) will show you where you ended up (ie, `/actual/pointed/directory`) – Olivier Dulac Dec 07 '20 at 12:42

3 Answers3

16

This can happen if the current directory is renamed or moved while you're in it.

For example:

$ mkdir /tmp/X
$ cd /tmp/X
$ mkdir Y Z
$ cd Y
$ touch a b c d e f
$ mv ../Y ../A
$ mv ../Z ../Y
$ echo $PWD
/tmp/X/Y
$ ls
a  b  c  d  e  f
$ ls $PWD
$ 

You can spot the difference in looking at the inode number of the directory:

$ ls -ldi . $PWD
26871815 drwxr-xr-x 2 sweh sweh 4096 Jul 12 17:27 ./
26872035 drwxr-xr-x 2 sweh sweh 4096 Jul 12 17:27 /tmp/X/Y/

You can also detect this because /bin/pwd returns a different value

$ /bin/pwd
/tmp/X/A
$ echo $PWD
/tmp/X/Y

Basically, $PWD is just where the shell thinks you are, not necessarily where you really are :-)

Stephen Harris
  • 42,369
  • 5
  • 94
  • 123
5

This is not caching.

You have to understand that in UNIX-like operating systems, there is a distinction between a name of a file, the file itself, and its contents. For example, a file might be found at /home/adam/myfile, but this maps to an 'inode' in the underlying filesystem. A hardlink is a different name for the same inode. The inode maps to some data somewhere else, so cat myfile involves asking the current directory what inode is associated with myfile, looking up that inode (usually on disk), and then looking for the data the inode maps to.

This is also true for directories, except their contents are different than regular files, as their contents consist of maps of file names to inodes.

So, when you change your working directory to /home/adam/cd2/adam_dev/rsim, a lookup is done to find the actual directory node with that name. After some time passes; maybe another process moves the directory to another path (a move in UNIX is usually more like a rename), or the directory is for whatever other reason unlinked from the parent directory (i.e., removed from the list of files of the parent directory node); the name /home/adam/cd2/adam_dev/rsim might no longer map to the same directory node, or might no longer map to anything at all. That directory node still exists, maybe somewhere else on the filesystem, and that's what you're seeing when you run ls . (. is actually like a hardlink that every directory has that points to itself. It's a real thing on the filesystem, not just syntax to mean 'the current directory').

Dylan Frese
  • 552
  • 4
  • 8
  • I'm glad it's not catching. Oh, wait, that's "caching." "Oh, I would know if I did something like that, right?" Well, a couple of weeks ago we reshuffled some directories to use a new repository for GIT. Some of these X-windows have been in the same directory for a long time and I bet that's what happened. I was changing files somewhere else. (Stephen Wright had a short bit where he said he had a light switch he kept switching until he got a postcard from a lady in Germany to cut it out.) – Adam N. Rosenberg Jul 12 '16 at 22:49
  • 1
    This is exactly caching. The shell stores the current directory in `$PWD`, but that *cache* is not updated when the directory is renamed/deleted. Cf. the other answer. – N.I. Jul 13 '16 at 08:00
  • 1
    @NajibIdrissi at least is not filesystem level caching, but an application level one. – Braiam Jul 13 '16 at 14:45
  • @NajibIdrissi It is not caching, in the sense that $PWD stores the *name* of your working directory, whereas your current working directory is an actual directory node. $PWD does not act as a cache, and has no mechanism for invalidation. – Dylan Frese Jul 13 '16 at 15:27
  • I think you should look up the actual definition of the word [cache](https://en.wikipedia.org/wiki/Cache_(computing)). The variable `$PWD` perfectly fits the definition for a cache of the name of the current directory, yes. – N.I. Jul 13 '16 at 15:36
  • 1
    @NajibIdrissi The existence of $PWD is not to enable a speedier lookup, there's no sense of a cache miss, there's no cache invalidation. Just because some fragment of data is or can be *out of date* does not make it a cache. – Dylan Frese Jul 14 '16 at 19:50
-1

You you put the command ls -d $PWD/* in a bash script it's working fine.

On MacOS

touch /usr/local/bin/lll
chmod 755 /usr/local/bin/lll

code /usr/local/bin/lll
#!/bin/bash
ls -d $PWD/*

Save the file

then open a new terminal window

use command lll and works fine.

  • 2
    What is the issue that this solves? It seems unrelated to the question at hand. – Kusalananda Dec 07 '20 at 12:11
  • 2
    `ls -d $PWD/*` would be fine at the prompt of your interactive shell in macos (as it's now zsh), but in bash, you'd need `ls -d "$PWD"/*`. – Stéphane Chazelas Dec 07 '20 at 12:11
  • If you create an alias like this `alias lll="ls -d $PWD/*"` in your `~/.zshrc file`, you get the wrong file path for the $PWD. If you create a bash script the command works fine. This is related to the $PWD path. – gkssjovi Dec 08 '20 at 13:05