0

I'm looking for all the alternative ways you can think of to list the files which are executable by anyone (owner, group, others) in the current directory and subdirectories.

For alternative ways, I mean those not using the find command:

find -L . -type f -perm -111
find -L . -type f -perm -a=x

One method that I'd like to see is a combination of ls and grep.

  • Are you in an OS that has the stat command? – Jeff Schaller Jan 11 '17 at 12:38
  • Yes, I didn't mention it, but as you can see from the question tags, the answers are meant for bash. – Bersekz Jan 11 '17 at 12:40
  • 2
    To be able to execute a file, one also needs to have search permission to the directory its in, so it's not just a matter of looking only at the file's permissions. – Stéphane Chazelas Jan 11 '17 at 12:40
  • bash has no stat builtin. zsh does have a stat builtin command, but many systems also have a stat command (with varying syntax) that you can call from any shell. – Stéphane Chazelas Jan 11 '17 at 12:42
  • @StéphaneChazelas You are right, although you can omit that control in this case and take the search permission for granted. – Bersekz Jan 11 '17 at 12:47
1

By using ls and grep:

ls -lAR | grep "^\-..x..x..x"

-l: Shows permissions in rwx format.

-R: Recursive.

  • A file with permissions -rx-rx-rx- is also executable by all. And you regex matches filenames too. – Kusalananda Jan 11 '17 at 12:37
  • As pointed out by Kusalanananda, your pattern doesn't match all possible cases. – Bersekz Jan 11 '17 at 12:38
  • @Kusalananda Correct, I misunderstood the question. Edit in order to use wildcards in grep. – Zumo de Vidrio Jan 11 '17 at 12:45
  • It will still match on the filenames, and it will display the ls -l output for each found file, but give no indication as to where this file is. – Kusalananda Jan 11 '17 at 12:51
  • 1
    For -paxmax-2x, it could match on the directory: header. Some ls implementations output ./directory:, some directory:. Which is why I used ls -lALR ./ in my answer (even ls -lALR . would not be enough with some implementations). – Stéphane Chazelas Jan 11 '17 at 13:56
3

ls output can not generally be post-processed reliably.

If you can guarantee that file names don't contain newline characters, you could do:

ls -AlLR ./| grep -E '^-(..[[:lower:]]){3}'

That is print lines that start with - (regular files only) and for which the third character in every group of 3 characters in the pemission field is a lowercase letter (in practice, that will generally be either x, s, l or t. Some systems may have extensions, but would make it a lower case letter if the file is executable).

Note that it will only print the file name, not its full path.

With zsh, you can also do:

printf '%s\n' **/*(D-.f+111)

Or:

printf '%s\n' **/*(D-.f:a+x:)

From within bash:

zsh -c 'printf "%s\n" **/*(D-.f+111)'

I suppose you're using -L in your find approach because for symlinks, you want to check the target of the symlink. That's the purpose of the - flag above.

Note however that another side effect of find's -L is that it would descend into symlinks to directories. The same will happen with ls -LR, not with that zsh solution above. If you really want to descend into symlinks to directories, replace the ** with ***, if you want to avoid descending into symlinks to directories with find, with GNU find (as found on Ubuntu), you can do:

find -L . \( ! -xtype l -o -prune \) -type f -perm -111

In any case, all those would fail to take into account files whose permissions alone would make them executable by every one but are sitting in directories that are not searchable by everyone. It could also give incorrect results if ACLs or other security measures are in place.

To also consider the searchability of the path components, you could do:

find -L . \( ! -xtype l -perm -111 -o -prune \) -perm -111

(assuming all the path components that lead to the current working directory itself are world-searchabe as well)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.