7

I am sure this is easy but i cant find it.

I am writing a bash script where i want to add a known user to a group. The group name is determined by the directory, which is sent through as a variable to that bash script.

so:

DIR="whatever"
GROUP=DIR groupname 
usermod -a -G $GROUP userx
2
  • I am not sure what a 'directory group owner' would be. A directory has an owner and a group. Those are not intertwined. Members of that group are listed in /etc/groups.
    – Hennes
    Apr 12, 2013 at 14:36
  • you're absolutely right, i just couldn't think of the right way to phrase it, "directory group" doesnt sound right.
    – fiscme
    Apr 12, 2013 at 14:58

2 Answers 2

13

stat -c %g <file> (Linux)

stat -f %g <file> (BSD)

Will return the group ID for the given <file>

EDIT:

stat -c %G <file> (Linux)

stat -f %Sg <file> (BSD)

Will return the group name.

2
  • excellent, thanks.. i knew (and desperately hoped) it would be easy!
    – fiscme
    Apr 12, 2013 at 15:00
  • And stat -c %U nfsmnt for the "user name of owner" as per the man page.
    – Nagev
    Apr 23, 2018 at 13:44
0

This is admittedly way more convoluted, but has the benefit of being more cross-platform friendly:

User:

\ls -l "$(dirname $TARGET_FILE)" | grep -v '^l' | grep " $(basename $TARGET_FILE)\$" | awk '{ print $3 }'

Group:

\ls -l "$(dirname $TARGET_FILE)" | grep -v '^l' | grep " $(basename $TARGET_FILE)\$" | awk '{ print $4 }'

Breaking it down:

  • Use \ls. The backslash avoids any shell aliases that might set default options like -F.
  • Build a -long format listing of the parent dir for $TARGET_FILE.
  • grep -v '^l' removes any symlinks that might point to $TARGET_FILE from the listing and passes on the rest.
  • Next narrow down the results to the single line from ls that ends in the basename of $TARGET_FILE. The leading ' ' (space) and trailing \$ are important to match the entire basename. (Otherwise old_file, file_new and file might all come up.)
  • Finally, pass the single ls -l row for the target file to awk, and grab the 3rd (or 4th) space-separated item as the user (or group) name.

Note that this implementation has trouble with relative directories. (Don't try to run it where TARGET_FILE=../ for example.) I'm sure it could be hardened some more using realpath, but that's not available on OS X, so we're back to platform-specific tools if we use that.

1
  • I've recently discovered a shortcoming of this approach. If you run this with a path to $TARGET_FILE where its parent directory is a symlink, you might not get any output. This is because the symlink name might not match the target folder name. So take the example where ~/public_html is a symlink to /var/www/sites/username/html/. Since "public_html" doesn't match "html", no output will be returned. I will update my answer if I find a solution for this.
    – beporter
    Jul 10, 2014 at 14:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .