2

I have to make a bash script: I've a directory and I'm reading all the files that are in the directory and I have to find the files to which the members of the group have no rights, after all this files I have to put into another file and set the write right (w) to the members of the group (g).

I figured out how to find the files where members of the group have no rights, but I don't know how to put the files into another file and set the writing right to the members of the group. Can somebody help me?

I write echo `find $1 ! -perm /g=rwx` just to see if the files are correctly taken.

#!/bin/bash

if [  $# -eq 0 ] 
        then echo "Nu exista parametri"
        exit 1
fi

if [ ! -d $1 ]
        then echo "It's not a directory"   #Check if the parameter is a directory
        exit 1
fi

echo `find $1 ! -perm /g=rwx`
Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
Ashley
  • 45
  • 5

2 Answers2

1

If by putting the files into another file you mean copying them, you can do that as follows:

cp source-file target-file

and you can then change the owning group with

chgrp your-group target-file

and, if still necessary, you can add write permission for that group with

chmod g+w target-file

For documentation run

man cp
man chgrp
man chmod
afdggfh
  • 135
  • 9
1

@afdggfh beet me to it, but a complete solution might look like:

files=$(find $dir ! -perm /g=rwx)
for file in $files; do
    trg=$trgdir/$(basename $file)
    cp $file $trg;
    chmod g+w $trg;
done;

---------------- EDIT -------------

Alternatively, you could add and -exec parameter to find. This parameter allows you to execute a command in place. In this case, {} represents the filename found, and \; represents the end of the exec command:

find $dir ! -perm /g=rwx -exec cp {} $trgdir \; -exec chmod g+w {} \;

This solution works for all filenames (including those with spaces, asterisks and newlines).

blackghost
  • 1,730
  • 11
  • 24
  • This breaks for file names with spaces in them, and file names undergo expansion. – Benjamin W. Apr 28 '17 at 17:18
  • Could you tell me what this line `trg=$trgdir/$(basename file)` does? – Ashley Apr 28 '17 at 17:24
  • this populates `$trg`, to hold the name of the target file. `$trgdir` is assumed to be the directory you are using for your target files. `$(basename $file)` is the filename without the directory. (oops, I forgot the `$` in my answer... updating), – blackghost Apr 28 '17 at 18:24
  • As @BenjaminW. pointed out, this will not work for filenames with spaces. If you want to handle these, you can either set `IFS` to be `\n`, or use a while loop as shown [here](http://stackoverflow.com/questions/7039130/iterate-over-list-of-files-with-spaces) – blackghost Apr 28 '17 at 18:29
  • The path expansion is more problematic, in my opinion. If you have a filename containing `*`, it'll expand to all files in the directory. – Benjamin W. Apr 28 '17 at 18:30
  • I just tried the `find` piped into `while`, and it handles both whitespace and `*`'s, but doesn't handle newlines... I just looked and found a [solution](http://stackoverflow.com/a/7039579/7673414) online that will handle those as well (though it's getting a bit hard to read... It would be simpler to do it as an `-exec` on the find at that point. I'll update my post. – blackghost Apr 28 '17 at 18:56
  • 1
    You can use `find -print0 | while read -d ''` for nul character delimited filenames – but `-exec` works fine and is safe with respect to expansions. – Benjamin W. Apr 28 '17 at 19:03