Recursive xattr fails horribly - xcode

I've been trying to figure out a way to recursively remove all of the xattr for some files, however, none of the previous methods seem to work anymore; there might be a newly introduced bug too?
$ xattr -rc .
option -r not recognized
$ xattr -c .
option -c not recognized
..and now the grand finale!
$ find . -exec xattr -l {} \;
com.apple.FinderInfo:
Traceback (most recent call last):
File "/usr/local/bin/xattr", line 11, in <module>
sys.exit(main())
File "/Library/Python/2.7/site-packages/xattr/tool.py", line 200, in main
print(_dump(attr_value))
File "/Library/Python/2.7/site-packages/xattr/tool.py", line 77, in _dump
printable = s.translate(_FILTER)
TypeError: character mapping must return integer, None or unicode
Oh look it found an xattr amongst the muck... it would be interesting to know how, what or who destroyed the xattr tool so badly. I just need to recursively remove extended attributes, really!

You appear to have a nonstandard xattr command installed in /usr/local/bin/xattr (the standard one that ships with macOS is /usr/bin/xattr). Those are Python errors, so maybe it's this one? Anyway, it doesn't use the same syntax as the standard one, so having it installed is going to cause confusion; I'd recommend either removing it or renaming it to something distinct; otherwise it's likely to break any scripts (yours or system) that try to use xattr.

This happened to me as well. and I believe is due to my $PATH
/usr/local/bin:/usr/bin
My user local bin comes before my system usr/bin.
Thanks to these posts I figured out the problem.
xattr was installed in two locations.
Show whether the target is a builtin, a function, an alias or an external executable.(Source) /
type -a xattr
# xattr is /usr/local/bin/xattr
# xattr is /usr/bin/xattr
and they are different for sure.
/usr/local/bin/xattr -h
usage: xattr [-slz] file [file ...]
xattr -p [-slz] attr_name file [file ...]
xattr -w [-sz] attr_name attr_value file [file ...]
xattr -d [-s] attr_name file [file ...]
The first form lists the names of all xattrs on the given file(s).
The second form (-p) prints the value of the xattr attr_name.
The third form (-w) sets the value of the xattr attr_name to attr_value.
The fourth form (-d) deletes the xattr attr_name.
options:
-h: print this help
-s: act on symbolic links themselves rather than their targets
-l: print long format (attr_name: attr_value)
-z: compress or decompress (if compressed) attribute value in zip format
VS.
/usr/bin/xattr -h
usage: xattr [-l] [-r] [-s] [-v] [-x] file [file ...]
xattr -p [-l] [-r] [-s] [-v] [-x] attr_name file [file ...]
xattr -w [-r] [-s] [-x] attr_name attr_value file [file ...]
xattr -d [-r] [-s] attr_name file [file ...]
xattr -c [-r] [-s] file [file ...]
The first form lists the names of all xattrs on the given file(s).
The second form (-p) prints the value of the xattr attr_name.
The third form (-w) sets the value of the xattr attr_name to the string attr_value.
The fourth form (-d) deletes the xattr attr_name.
The fifth form (-c) deletes (clears) all xattrs.
options:
-h: print this help
-l: print long format (attr_name: attr_value and hex output has offsets and
ascii representation)
-r: act recursively
-s: act on the symbolic link itself rather than what the link points to
-v: also print filename (automatic with -r and with multiple files)
-x: attr_value is represented as a hex string for input and output
So, if you do want to keep both for whatever reason, then you can just call them explicitly like so:
/usr/bin/xattr -lr ~
/usr/local/bin/xattr -l ~

Related

What does # in `-rw-r--r--#` mean in the `ls -l` output?

I was examining output of ls -l in by bash completion folder on Mac OS X
$ ls -alrth /usr/local/etc/bash_completion.d/docker-machine*
-rw-r--r--# 1 abhimskywalker staff 1.4K Jun 13 19:04 /usr/local/etc/bash_completion.d/docker-machine-prompt.bash
-rw-r--r--# 1 abhimskywalker staff 1.5K Jun 13 19:36 /usr/local/etc/bash_completion.d/docker-machine-wrapper.bash
-rw-r--r--# 1 abhimskywalker staff 6.8K Jun 13 19:37 /usr/local/etc/bash_completion.d/docker-machine.bash
I could not understand what does this # mean in -rw-r--r--#?
It indicates that the file has extended attributes. You can use the xattr command-line utility to view and modify them:
xattr -l file # lists the names of all xattrs.
xattr -w attr_name attr_value file # sets xattr attr_name to attr_value.
xattr -d attr_name file # deletes xattr attr_name.
xattr -c file # deletes all xattrs.
xattr -h # prints help
You can also use ls -l# to see more information about those extended attributes.
From the osx ls man page:
The Long Format
If the file or directory has extended attributes, the permissions field printed by the -l option is followed by an # character. Otherwise, if the file or directory has extended security information, the permissions field printed by the -l option is followed by a + character.
And
-# Display extended attribute keys and sizes in long (-l) output.

mv command not working on mac

Here is the part of the makefile that is giving me issues:
-#mv -f -t ./ $(LIBPATH)/userfiles/*
When I run the makefile on Ubuntu it works fine however when running on my Mac I get the following error:
mv: illegal option -- t usage: mv [-f | -i | -n] [-v] source target
mv [-f | -i | -n] [-v] source ... directory
The -t flag is not defined in the man pages of my mac so I'm wondering how I can get around this.
Just put the destination at the end like how mv is normally used:
-#mv -f $(LIBPATH)/userfiles/* .
You are allowed to have multiple sources (such as the expanded wildcard here). The last argument is the destination. The -t flag is just a way to change this ordering if you have to for some reason, and (as you discovered) it is not always available.
Install coreutils by typing the following command in the terminal:
brew install coreutils
Commands also provided by macOS and the commands dir, dircolors, vdir have been installed with the prefix "g".
If you need to use these commands with their normal names, you can add a "gnubin" directory to your PATH with:
PATH="$(brew --prefix)/opt/coreutils/libexec/gnubin:$PATH"
Reference:
coreutils - Homebrew Formulae

grep: Unknown option -C

I want grep to print 2 lines before and after the matching line.
I am using GnuWin32 grep(2.5.4). But it is showing error as follows:
grep: Unknown option -C
Usage: grep [-clqinsvxEF] [-bI] [-e pattern] [-f patternfile] [pattern] [file ...]
As per my understanding from the error, the -C option is not supported by GnuWin32.
So my doubt is The GnuWin32 grep will not support -C option or any updated version is there for GnuWin32 grep which would support -C option....

How do I remove the "extended attributes" on a file in Mac OS X?

I have an AppleScript script that runs a stress test. Part of the test is to open, save, and close certain files. Somehow, the files have picked up some "extended attributes" that prohibit the files from being saved. That causes the stress test to fail.
How do I remove the extended attributes?
Use the xattr command. You can inspect the extended attributes:
$ xattr s.7z
com.apple.metadata:kMDItemWhereFroms
com.apple.quarantine
and use the -d option to delete one extended attribute:
$ xattr -d com.apple.quarantine s.7z
$ xattr s.7z
com.apple.metadata:kMDItemWhereFroms
you can also use the -c option to remove all extended attributes:
$ xattr -c s.7z
$ xattr s.7z
xattr -h will show you the command line options, and xattr has a man page.
Removing a Single Attribute on a Single File
See Bavarious's answer.
To Remove All Extended Attributes On a Single File
Use xattr with the -c flag to "clear" the attributes:
xattr -c yourfile.txt
To Remove All Extended Attributes On Many Files
To recursively remove extended attributes on all files in a directory, combine the -c "clear" flag with the -r recursive flag:
xattr -rc /path/to/directory
A Tip for Mac OS X Users
Have a long path with spaces or special characters?
Open Terminal.app and start typing xattr -rc, include a trailing space, and then then drag the file or folder to the Terminal.app window and it will automatically add the full path with proper escaping.
Try using:
xattr -rd com.apple.quarantine directoryname
This takes care of recursively removing the pesky attribute everywhere.
Answer (Individual Files)
1. Showcase keys to use in selection.
xattr ~/Desktop/screenshot\ 2019-10-23\ at\ 010212.png
# com.apple.FinderInfo
# com.apple.lastuseddate#PS
# com.apple.metadata:kMDItemIsScreenCapture
# com.apple.metadata:kMDItemScreenCaptureGlobalRect
# com.apple.metadata:kMDItemScreenCaptureType
2. Pick a Key to delete.
xattr -d com.apple.lastuseddate#PS ~/Desktop/screenshot\ 2019-10-23\ at\ 010212.png
xattr -d kMDItemIsScreenCapture ~/Desktop/screenshot\ 2019-10-23\ at\ 010212.png
3. Showcase keys again to see they have been removed.
xattr -l ~/Desktop/screenshot\ 2019-10-23\ at\ 010212.png
# com.apple.FinderInfo
# com.apple.metadata:kMDItemScreenCaptureGlobalRect
# com.apple.metadata:kMDItemScreenCaptureType
4. Lastly, REMOVE ALL keys for a particular file
xattr -c ~/Desktop/screenshot\ 2019-10-23\ at\ 010212.png
Answer (All Files In A Directory)
1. Showcase keys to use in selection.
xattr -r ~/Desktop
2. Remove a Specific Key for EVERY FILE in a directory
xattr -rd com.apple.FinderInfo ~/Desktop
3. Remove ALL keys on EVERY FILE in a directory
xattr -rc ~/Desktop
WARN: Once you delete these you DON'T get them back!
FAULT ERROR: There is NO UNDO.
Errors
I wanted to address the error's people are getting.
Because the errors drove me nuts too...
On a mac if you install xattr in python, then your environment may have an issue.
There are two different paths on my mac for xattr
type -a xattr
# xattr is /usr/local/bin/xattr # PYTHON Installed Version
# xattr is /usr/bin/xattr # Mac OSX Installed Version
So in one of the example's where -c will not work in xargs is because in bash you default to the non-python version.
Works with -c
/usr/bin/xattr -c
Does NOT Work with -c
/usr/local/bin/xattr -c
# option -c not recognized
My Shell/Terminal defaults to /usr/local/bin/xattr because my $PATH
/usr/local/bin: is before /usr/bin: which I believe is the default.
I can prove this because, if you try to uninstall the python xattr you will see:
pip3 uninstall xattr
Uninstalling xattr-0.9.6:
Would remove:
/usr/local/bin/xattr
/usr/local/lib/python3.7/site-packages/xattr-0.9.6.dist-info/*
/usr/local/lib/python3.7/site-packages/xattr/*
Proceed (y/n)?
Workarounds
To Fix option -c not recognized Errors.
Uninstall any Python xattr you may have: pip3 uninstall xattr
Close all Terminal windows & quit Terminal
Reopen a new Terminal window.
ReRun xattr command and it should now work.
OR
If you want to keep the Python xattr then use
/usr/bin/xattr
for any Shell commands in Terminal
Example:
Python's version of xattr doesn't handle images at all:
Good-Mac:~ JayRizzo$ xattr ~/Desktop/screenshot\ 2019-10-23\ at\ 010212.png
# com.apple.FinderInfo
# Traceback (most recent call last):
# File "/usr/local/bin/xattr", line 8, in <module>
# sys.exit(main())
# File "/usr/local/lib/python3.7/site-packages/xattr/tool.py", line 196, in main
# attr_value = attr_value.decode('utf-8')
# UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb0 in position 2: invalid start byte
Good-Mac:~ JayRizzo$ /usr/bin/xattr ~/Desktop/screenshot\ 2019-10-23\ at\ 010212.png
# com.apple.FinderInfo
# com.apple.lastuseddate#PS
# com.apple.metadata:kMDItemIsScreenCapture
# com.apple.metadata:kMDItemScreenCaptureGlobalRect
# com.apple.metadata:kMDItemScreenCaptureType
Man Pages
MAN PAGE for OSX xattr
MAN PAGE for Python xattr VERSION 0.6.4
NOTE: I could not find the python help page for current VERSION 0.9.6
Thanks for Reading!
Another recursive approach:
# change directory to target folder:
cd /Volumes/path/to/folder
# find all things of type "f" (file),
# then pipe "|" each result as an argument (xargs -0)
# to the "xattr -c" command:
find . -type f -print0 | xargs -0 xattr -c
# Sometimes you may have to use a star * instead of the dot.
# The dot just means "here" (whereever your cd'd to
find * -type f -print0 | xargs -0 xattr -c

How to emulate 'cp --update' behavior on Mac OS X?

The GNU/Linux version of cp has a nice --update flag:
-u, --update
copy only when the SOURCE file is newer than the destination file or when the destination file is missing
The Mac OS X version of cp lacks this flag.
What is the best way to get the behavior of cp --update by using built-in system command line programs? I want to avoid installing any extra tools (including the GNU version of cp).
rsync has an -u/--update option that works just like GNU cp:
$ rsync -u src dest
Also look at rsync's other options, which are probably what you actually want:
-l, --links copy symlinks as symlinks
-H, --hard-links preserve hard links
-p, --perms preserve permissions
--executability preserve executability
-o, --owner preserve owner (super-user only)
-g, --group preserve group
--devices preserve device files (super-user only)
--specials preserve special files
-D same as --devices --specials
-t, --times preserve times
-a, --archive
This is equivalent to -rlptgoD. It is a quick way of saying you want recursion
and want to preserve almost everything (with -H being a notable omission). The
only exception to the above equivalence is when --files-from is specified, in which
case -r is not implied.
Note that -a does not preserve hardlinks, because finding multiply-linked files is
expensive. You must separately specify -H.

Resources