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 :) Aug 13 '13 at 14:58
  • 2
    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.

  • Your answer might be more helpful if you describe the diff you provide.
    – HalosGhost
    Jun 23 '14 at 2:59
  • 3
    This seems useful, but I don’t have a good way to test it. Any chance of submitting a patch to coreutils? Jun 25 '14 at 21:39
  • 1
    Would you be able to post the patch here or on GitHub or something?
    – Max Coplan
    Sep 6 '19 at 23:07
  • Absolutely incredible! This is precisely the patch I needed and can't believe I just found this. I'm going to try compiling this into GNU coreutils 8.32 ls on iOS for jailbroken devices. Thanks a lot!! Jul 6 at 6:29
  • @wilywampa I compiled this patch on coreutils 8.22 as you said, but when I use ls -l or ls -lF, I can see the extra space after -rw--r--r-, but it never displays the @ for xattr, even on /User/Media/DCIM/123APPLE which I can use other tools to confirm all the camera roll contains xattrs. I'm compiling with clang 10 on iOS 12.4 jailbroken, APFS. Any ideas? Aug 23 at 7:24

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.

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.