5

I have read this and this, and found that my problem is different and more specific.

I understand the following points.

  • +x on the directory grants access to files inodes through this specific directory
  • meta information of a file, which is used by ls -l, is stored in its i-node, but file name does not belong to that

From the 2 points above, since ls without -l does not need to access the i-nodes of the files in the directory, it should successfully list the file names and return 0.

However, when I tried it on my machine, the file names are listed, but there were some warnings like permission denied, and the return code is 1.

b03705028@linux7 [~/test] chmod 500 permission/
b03705028@linux7 [~/test] ls --color=no permission/
f1*
b03705028@linux7 [~/test] chmod 400 permission/
b03705028@linux7 [~/test] ls --color=no permission/
ls: 無法存取 'permission/f1': 拒絕不符權限的操作
f1
b03705028@linux7 [~/test] echo $0
bash

The Chinese characters basically talk about permission denied

My unix distribution is Linux 4.17.11-arch1

David Chen
  • 151
  • 5
  • Hi David, unfortunately I cannot reproduce your problem. Using bash `rm -rf lala; mkdir lala; chmod 400 lala; command ls lala` is successful for me. The `command` only makes sure that no alias of`ls` is used. Could you please extend your question with the exact commands you type in to show the problem? (i.e., make a minimal working demonstration of what you observe) – stefan Nov 06 '18 at 11:32
  • Hi stefan, I use `echo $0` to verify that I'm using `bash` too. May I ask which Unix distribution are you using? I've updated the problem to include the commands I used. – David Chen Nov 06 '18 at 11:35
  • What happens if you run `/bin/ls` directly? It's very likely that you have an alias or function in your shell that's making it try to get file stats. The `*` at the end of `f1` makes me think there's the `-F` flag – Stephen Harris Nov 06 '18 at 11:42
  • @StephenHarris Yeah that's the reason. problem solved. you guys are amazing. – David Chen Nov 06 '18 at 11:46
  • Yes, I assume that your `ls` is an alias and uses the `-F` flag to classify the filles, see `ls`(1). This would try to access `f1` in order to classify it and append an asterisk. Using `ls --color=no` only appends to the alias. Try `command ls` instead. I'm using ArchLinux, should not make a difference. – stefan Nov 06 '18 at 11:48
  • Thank you very much, now I'm gonna try to understand `command` :) – David Chen Nov 06 '18 at 11:55

1 Answers1

8

I suspect ls in your case is an alias to something like ls --color=auto; in that case, ls tries to find information about the files contained inside the directory to determine which colour to use.

ls --color=no

should list the directory without complaining.

If it still complains, then you may be using another option, like -F or --classify, that needs to access file metadata (-F/--classify looks at the file type, for example).

To be sure that you run ls without going through an alias, use either of

command ls

or

\ls

To remove an alias for ls, use

unalias ls
Kusalananda
  • 320,670
  • 36
  • 633
  • 936
Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
  • Thank you for the answer. I just tried `ls --color=no`, but the result is exactly the same. I also checked `/etc/bash.bashrc` and `~/.bashrc`, and there are no such aliases. Am I missing something? – David Chen Nov 06 '18 at 11:11
  • @DavidChen What does `type ls` return? – Kusalananda Nov 06 '18 at 11:38
  • @Kusalananda `ls is alias of「ls --color -F」` I guess `-F` here is the reason why I still get return code as 1 even using `--clor=no`? – David Chen Nov 06 '18 at 11:45
  • @DavidChen Yes, that option needs to access the filetype of each file. – Kusalananda Nov 06 '18 at 11:46
  • @Kusalananda I know this is kind of unrelated to the original question, but where can the alias be defined other than `/etc/bash.bashrc` and `~/.bashrc`? – David Chen Nov 06 '18 at 11:53
  • @DavidChen `/etc/profile` or in a file under `/etc/profile.d`? – Kusalananda Nov 06 '18 at 11:54
  • @Kusalananda No luck. I found [this question](https://unix.stackexchange.com/questions/21251/execute-vs-read-bit-how-do-directory-permissions-in-linux-work), and it seems pretty hard to trace where an alias is defined. Thank you for your time. – David Chen Nov 06 '18 at 12:05
  • @Kusalananda It might be worth noting that `unalias ls` is only effective in the current shell life cycle. I'm not sure about the terms, but I mean if you close the terminal and ssh again, the aliases will come into play again. – David Chen Nov 06 '18 at 12:13
  • 2
    @DavidChen Not if you put it in your `~/.bashrc` file. – Kusalananda Nov 06 '18 at 12:25
  • I believe `'ls'` or `"ls"` (putting the command in quotes) will also bypass the alias, while `/bin/ls` will run an external `ls` utility and ignore any bash-specific features. – IMSoP Nov 06 '18 at 16:28
  • Replacing `-F` with `--file-type` (which will work the same except for appending an `*` to executables) will also prevent `ls` from calling stat(2) on entries. `ls` is using the `d_type` field from the [dirent](http://man7.org/linux/man-pages/man3/readdir.3.html) struct. (that works on most file systems -- minixfs being a notable exception). The only need for that stat() call is to tell apart the executables by looking at their permissions. –  Nov 06 '18 at 18:42