Duplicate with exact copy doesn't preserve the permissions.

I’m trying to duplicate/copy a finder selection to a target folder preserving the source permissions.
According the finder dictionary, appending “with exact copy” should do the trick.
Unfortunately my take of that doesn’t seem to work:

tell application "Finder"
	activate
	set mySelection to selection as alias list
	set targetFolder to choose folder
	if targetFolder is false then error number -128
	repeat with i in mySelection
		set sourceItem to i
		duplicate sourceItem to targetFolder with replacing and exact copy
	end repeat
end tell

Duplicate with replacing works but, the “exact copy” part doesn’t preserve special permissions of the source.
I note that doing it manually with “Command-C” followed by “Shift-Option-Command-V” does work.
Please, what’s wrong with my script? What is the correct syntax to preserve the source permissions?

Browser: Safari 536.30.1
Operating System: Mac OS X (10.8)

I would reduce the Finder’s role to the strict minimum :


tell application "Finder"
	activate
	set mySelection to selection as alias list
end tell

set targetFolder to choose folder
--if targetFolder is false then error number -128
# quote the target path here to do it only once
set qpTargetFolder to quoted form of POSIX path of targetFolder
repeat with i in mySelection
	do shell script "cp -p " & quoted form of POSIX path of i & space & qpTargetFolder
end repeat

KOENIG Yvan (VALLAURIS, France) lundi 26 août 2013 18:37:43

Thanks Yvan,
I agree with avoiding the Finder whenever possible.

The "cp -p " command works for files but not for folders or bundles, such as apps.
I tried "cp -pR " but that copies the contents of folders or bundles instead of the folders and bundles themselves.
To copy the folders, ‘cp’ requires folders without trailing ‘/’. I could do something like:

if kind of i is "Folder" then set i to (container of i as text) & name of i

But, it seems cumbersome and I don’t know how to cover all kinds of bundles.
The reason I tried to use ‘duplicate’ was that it does work for files as well as bundles and folders with trailing “:”.
To summarise:
(1) Is there a shell command to copy any type of file, bundle or folder, while preserving the attributes and folder structures?
(2) Why doesn’t “duplicate sourceItem to targetFolder with exact copy” work?

Cheers,
Chris

tell application "Finder"
	activate
	set mySelection to selection as alias list
end tell
set targetFolder to choose folder
set qpTargetFolder to quoted form of POSIX path of targetFolder
repeat with i in mySelection
	set sourceItem to i as text
# If i is a folder or a package, sourceItem ends with a colon. Just remove it and cp will work flawlessly
	if sourceItem ends with ":" then set sourceItem to text 1 thru -2 of sourceItem
	do shell script "cp -a " & quoted form of POSIX path of sourceItem & space & qpTargetFolder
end repeat

As I don’t use the Finder for such tasks for years, I don’t know the answer.

KOENIG Yvan (VALLAURIS, France) lundi 26 août 2013 20:35:56

This works well now to copy files, bundles or folders, while preserving folder and bundle structures.
Unfortunately, It doesn’t preserve special permissions.
For instance, I tried to copy two apps downloaded from the Mac App Store.
Such apps have the permissions system=Read & Write, wheel=Read only, everyone=Read only.
The copy gets the permissions chris (Me)=Read & Write, admin=Read only, everyone=Read only.
Is there any way of preserving the permissions as well?

Is it possible that the inability of preserving special permissions is a bug in ML 10.8.4, affecting both ‘duplicate’ and ‘cp’?

Hello.

I don’t think that is a bug, wheel, is the group that root belongs to, and as it stands, you don’t have root permissions, so the demotion to admin is natural. Try copying the apps manuall from the /Applications folder, to somewhere where you copied the app with the script.

Part of the problem may also be, that new rights and permissions are calculated, they also depend upon where the “file” is placed.

Thanks McUsrII,
I did try to copy the same source files to the same target folder manually using “Command-C” followed by “Shift-Option-Command-V” and it did work. The copy has the same permissions (ownership) as the source.
I need however to do it in a script to copy certain plist files from /Library/Preferences/ and MAS apps from /Applications/.

Would it work by having System Events mimicking the manual keystrokes “Shift-Option-Command-V”?
Please, I need help with the code for that.

This code does the trick but here it ask me to authenticate which is a bit annoying.


tell application "Finder"
	activate
	set mySelection to selection as alias list
end tell
tell application "System Events" to tell process "Finder"
	keystroke "c" using {command down}
end tell
activate -- Yvan, I added this to promote the choose dialog 
set targetFolder to choose folder

tell application "Finder"
	activate
	open folder targetFolder
end tell
tell application "System Events" to tell process "Finder"
	keystroke "v" using {shift down, option down, command down}
	keystroke return
end tell

When we apply the same scheme by hand, authentification is not required.
I gues that it’s because when we do that, the system knows who is triggering it.
When the task is triggered by a script, the system ignore who is really driving the script.

I have an other idea :
read the sourceItem’s permissions and apply them to the copy.
Alas I’m quite sure that authentification would be required too.

KOENIG Yvan (VALLAURIS, France) mardi 27 août 2013 09:38:41

Thanks Yvan,
The use of System Event keystroke mimicking works very well. I don’t mind having to authenticate because I will have to run my actual script only occasionally.
But, your comments gave me the idea to add “with administrator privileges” to your “cp” script. It works perfectly :cool:
Here it is:

tell application "Finder"
	activate
	set mySelection to selection as alias list
end tell
activate
set targetFolder to choose folder
set qpTargetFolder to quoted form of POSIX path of targetFolder
repeat with i in mySelection
	set sourceItem to i as text
	if sourceItem ends with ":" then set sourceItem to text 1 thru -2 of sourceItem
	do shell script "cp -a " & quoted form of POSIX path of sourceItem ¬
		& space & qpTargetFolder with administrator privileges
end repeat

Cheers,
Chris