Removing all extended attributes from a directory tree

Here’s a simple one-liner I came up with to remove all HFS+ extended attributes on all files and directories below the current one in Mac OS X. Useful before creating a tar file that will be shared with non-Mac users (tar in OSX will create additional “resource” files to store extended attributes, which when untared on a Mac will be correctly reinstated, but in other systems will leave spurious hidden files all over the place).

for i in $(ls -Rl@ | grep '^      ' | awk '{print $1}' | sort -u); \
   do echo Removing $i ... >&2;  \
   find . | xargs xattr -d $i 2>/dev/null ; done

The space after the caret in the grep command is produced by typing Ctrl-V and then Tab, to insert a Tab character.


24 responses to “Removing all extended attributes from a directory tree

  1. Dominik Hoffmann

    This only puts out the name of the attribute it’s supposed to remove, but doesn’t actually. I am running this in sudo mode.

  2. Dominik: if you are typing “sudo” followed by the command shown, then only the first command (the “for” is executed as root, so the attributes will not be removed (the xargs command is the one that needs to be run as root). You need to enter a root shell (you could run “sudo bash”) and then type the command in that shell so that all the commands execute as root.

  3. Dominik Hoffmann

    Hi Hitchhiker: I had executed the command inside a root shell, via sudo -s. — Dominik

  4. Do you get any errors when executing the command? I see nothing wrong in the command as shown, it should work properly.

  5. Dominik: you could try removing the “2> /dev/null” after the xattr command, to have errors shown on the terminal.

  6. Dominik Hoffmann

    This is what I see:

    echo Removing …
    xargs: unterminated quote

    Dominik Hoffmann

  7. The “unterminated quote” message makes me think there is a filename in the tree you are processing that has a quote character (single or double quote) in it. You could try adding the -t option to xargs (xargs -t xattr .., still leaving out the “2> /dev/null”), which will print the commands it executes, and see which command is printed before the error.

  8. Dominik Hoffmann

    xargs -t doesn’t output anything.

  9. Dominik Hoffmann

    Okay, I made the working directory ~/.ssh/.

    This time it worked:

    echo Removing …
    xattr -d . ./authorized_keys ./id_dsa ./ ./known_hosts
    echo Removing …
    xattr -d . ./authorized_keys ./id_dsa ./ ./known_hosts

    However, with the working directory being ~ and the -R option removed from the ls instruction I have

    xargs: unterminated quote
    echo Removing …
    xargs: unterminated quote
    echo Removing …
    xargs: unterminated quote

  10. Dominik Hoffmann

    This entry in the forums,, pointed me in the right direction. It suggests the use of the -0 option in xargs in conjunction with the -print0 primary in find. It therefore works, when I execute

    for i in $(ls -Rl@ | grep ‘^ ‘ | awk ‘{print $1}’ | sort -u); do echo echo Removing $i … >&2; find . -print0 | xargs -0t xattr -d $i 2>/dev/null ; done

    Now it would be interesting to know, why you guys don’t need those modifications and I do.


  11. Dominik: I figured that was the problem. You must have some files with quote characters in them (or some other punctuation), which is why it doesn’t work with the standard separators.

    Glad you got it to work!

  12. Pingback: PantherModem » Blog Archive » GCC Says: error: expected unqualified-id before ‘OTHER’ token

  13. Many thanks on putting this script together. Is there a way to prevent these extended attributes from being generated in the first place? I ask because I have never noticed this before upgrading to 10.5, and other computers using the 10.5 do not appear to create these extended attributes. I often tar directories containing 1000s of files, and the presence of extended attributes makes the compressing/decompressing very slow.

  14. You can simplify this quite a lot.

    find . -exec xattr -d {} ;

    Doesn't give you the satisfying output, but it works. 🙂

  15. Wait! No it doesn't. Wish I could delete that post…

  16. Justin: it doesn't, because you have to give to xattr -d the attribute you want to delete. That's what the script does – first find all the attributes that exist under the directory, and then loop over them, removing them in sequence.

  17. Should this remove the info found in the "Get Info" menu item? After I ran this, I still see a URL from where I downloaded my files from…

  18. is there a reason why "echo" is listed twice?

  19. It also might be worth mentioning that you can create copy of a file or directory that doesn't have any extended attributes by passing the -X option to the cp command.

    For example, if you want to make a clean tar file of the directory "my_files", you could do the following:

    # copy my_files to the Desktop, excluding extended attributes
    cp -rX ~/Documents/my_files ~/Desktop/my_files

    # go to Desktop
    cd ~/Desktop

    # create the tar file, excluding .DS_Store files
    tar cjvf my_files.tar.bz2 –exclude .DS_Store my_files

    # remove the copy
    rm -r my_files

  20. I was unable to get the xattr stuff to remove the extended attributes from my Time Machine copies (I had done them originally with -p which was a bad idea, I suppose). However, using 'cp -rX' along with renames (and admin access) solved my problem.

  21. How to remove extended attribute from NTFS , using win32 API’s

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s