Shell – See extended attributes with coreutils ls on Mac

coreutilsosxshellxattr

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'
else
    alias ls='/bin/ls -G'
fi

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?

Best Answer

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>
+
  #if HAVE_LANGINFO_CODESET
  # 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.

Related Question