0

I have two bundles(directories) with identical hierarchy and files inside. I need to copy permissions of each item inside source bundle into files located in destinations bundle. I should not copy the files, only permissions.

Is it possible to do with shell script or should I go hard way and write app to do this?

Pablo
  • 28,133
  • 34
  • 125
  • 215
  • If the file's *contents* really are identical, `rsync` should work. It will copy only the bits of the file that need copying (in this case, only the file metadata). – chepner Nov 20 '13 at 20:40
  • If you do `find dir/ -printf "%m %f\n"` you will get the permissions from the `%m`. Then I guess it must be a matter of tricking with `-exec`... – fedorqui Nov 20 '13 at 20:43
  • @chepner: nope, the contents is not bit identical, but file names/paths are same. – Pablo Nov 20 '13 at 20:43
  • @fedorqui: not sure how to put this together... Also `-printf` is not there for `osx`. – Pablo Nov 20 '13 at 20:44

1 Answers1

2

It's not bash, but zsh is available in OS X, so you might try the following (I'm using % for the prompt to indicate when you are in zsh; for> is a secondary prompt)

$ zsh
% for x in source/**/*; do
for> chmod $(stat -f "%p" $x) ${x/^source/dest}
for> done
% exit
$

The for loop iterates over all files under source, recursively. stat -f "%p" $x outputs the permissions for a file in the source directory, to use as the argument for the command that changes the permissions of the corresponding file (i.e., replace "source" with "dest" in its name) in the destination directory.

(Actually, that loop would work in bash 4 as well, but as you may have noticed, OS X still ships with bash 3.2.)


As a standalone script named foo.zsh:

#!/bin/zsh
for x in source/**/*; do
  chmod $(stat -f "%p" $x) ${x/^source/dest}
done

$ chmod +x foo.zsh
$ ./foo.zsh

or simply

$ zsh foo.zsh
chepner
  • 497,756
  • 71
  • 530
  • 681
  • Oh, so `stat` with `%p` prints the permissions. Didn't know, looks way better than my `find`. +1 – fedorqui Nov 20 '13 at 21:03
  • @chepner: it works when running from command line. However, when I converted this into script regex part doesn't work with beginning of string mark. If I remove it, substitution take place. The strange thing that if I echo `$x`, it gives me correct beginning, which should be replaced. I could live with that, but to be on safe side I would like to know where is the problem. – Pablo Nov 20 '13 at 21:59
  • It sounds like you may be creating a `bash` script, not a `zsh` script. I'll update. – chepner Nov 20 '13 at 22:10
  • @chepner: that's how I also converted. Removing `^` make it work. – Pablo Nov 20 '13 at 22:24
  • Oh, sorry about that. I meant to anchor `source` to the beginning of the string, but used the wrong character. `${x/#source/dest}`. – chepner Nov 21 '13 at 13:28