I have coreutils installed via MacPorts on my Mac running OS X 10.8.4. I have ls set to use the coreutils version of ls [(GNU coreutils) 8.21] when available:

if [ -e /opt/local/libexec/gnubin ]; then
    alias ls='/opt/local/libexec/gnubin/ls --color=auto'
    alias ls='/bin/ls -G'

When I run ls -l in a directory with files known to have extended attributes (xattrs), I expect to see an @ sign after the permissions in those listings. However, I see no @ sign. If I run /bin/ls -l, I get the @ sign.

File listing from /bin/ls -l:

-rw-r--r--@  1 zev.eisenberg  staff  132887 Jul 19 16:24 flowchart.graffle

File listing from ls -l (using coreutils):

-rw-r--r--  1 zev.eisenberg staff 132887 Jul 19 16:24 flowchart.graffle

How can I get the coreutils version of ls to show me the @ sign when xattrs are present?

  • 1
    Your examples show that coreutils' ls shows the @ and /bin/ls does not. Is that correct, or swapped? – mrb Aug 12 '13 at 18:24
  • I hate to ruin a good question, but where does zsh enter into the picture? :) – user Aug 12 '13 at 19:39
  • What's the version of ls + coreutils? $ ls --version. – slm Aug 13 '13 at 1:30
  • Michael, it enters because I’m a noob at some of this stuff, and I put in zsh because I use it, and in case it might be relevant :) – Zev Eisenberg Aug 13 '13 at 14:58
  • 1
    Coreutils for OSX isn't built with the same attribute functions, it's made for SELinux (ls -Z on osx shows ?) I'm pretty sure you won't get the same output as the builtin ls. – Mark Cohen Aug 20 '13 at 22:11

You can add extended attributes to coreutils ls. This is based on coreutils-8.22:

*** 59,62 ****
--- 59,64 ----
  #include <wchar.h>

+ #include <sys/xattr.h>
  # include <langinfo.h>
*** 3056,3059 ****
--- 3058,3062 ----
                              : ACL_T_YES));
            any_has_acl |= f->acl_type != ACL_T_NONE;
+           any_has_acl |= listxattr(f->name, NULL, 0, XATTR_NOFOLLOW);

            if (err)
*** 3811,3814 ****
--- 3814,3819 ----
    if (! any_has_acl)
      modebuf[10] = '\0';
+   else if (listxattr(f->name, NULL, 0, XATTR_NOFOLLOW) > 0)
+     modebuf[10] = '@';
    else if (f->acl_type == ACL_T_SELINUX_ONLY)
      modebuf[10] = '.';

Basically I looked in the OS X ls source to find the logic for printing the @ (the listxattr call) and hooked that into where coreutils ls puts a symbol after the permissions. The three changes are:

  1. Including xattr.h
  2. Set any_has_acl if any of the listings have extended attributes - this is required so that listings that don't have extended attributes have a space inserted after the permissions to line things up
  3. Do the actual check by calling listxattr and conditionally setting the @ symbol - might be worth noting that they way this is written will show only the @ if there are both extended attributes and ACL

The XATTR_NOFOLLOW argument tells listxattr not to follow symlinks. That argument is used in OS X ls.

| improve this answer | |
  • Your answer might be more helpful if you describe the diff you provide. – HalosGhost Jun 23 '14 at 2:59
  • 2
    This seems useful, but I don’t have a good way to test it. Any chance of submitting a patch to coreutils? – Zev Eisenberg Jun 25 '14 at 21:39
  • Would you be able to post the patch here or on GitHub or something? – Max Coplan Sep 6 '19 at 23:07

I believe Mark Cohen’s comment is correct: this functionality seems to be absent from the coreutils version of ls. I didn’t actually have a good reason to be using coreutils ls, so I’ve switched back to the built-in BSD version.

| improve this answer | |

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.