Parsing "id" strings in a Shell Script?
Hello Dave. I need a Bash shell script that creates a directories with the group names automatically when user logs in to the system, in their home directory.
For example, user "sandy" might have the following set of groups from the 'id' command:
uid=10002(sandy) gid=119(rtkit) groups=119(rtkit),10001(admin),10003(pr007drdl)
and the directories "rtkit", "admin" and "pr007drdl" should then be created. How do I do it?
I think this falls into the category of "Dave, can you do my homework?" but since it's an interesting problem, I'll spend some time talking about how to do this sort of simple parsing and then wrap it with with a 'for' loop that steps through each value.
There are also nuances to your assignment that are important. For example, trying to create a directory that already exists is sloppy and poor coding, so part of what you need to do is test for the existence of the group subdirectory prior to requesting its creation. Sure you can use a "force" flag or an "ignore error" flag on the call to 'mkdir', but that's cheap coding and if we're going to write something, let's write it well, right?
So here's the basic approach I'm envisioning: in the .login file extract one or more group names from the output of the 'id' command. For each value test to see if it exists yet as a subdirectory. If it does, move to the next value. If it doesn't, create it.
Let's see how that looks as a script.
The first step is to break down the 'id' string into the individual group elements. If you look at the output of "id", you'll see that there's a regular pattern to the results, so it's not too bad. Here's the output of my own id string:
uid=501(taylor) gid=20(staff) groups=20(staff),401(com.apple.access_screensharing),404(com.apple.sharepoint.group.3), 402(com.apple.sharepoint.group.1),403(com.apple.sharepoint.group.2),12(everyone),33(_appstore),61(localaccounts), 79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),100(_lpoperator),204(_developer)
Kind of crazy complicated, but it's still three fields separated by spaces, the third of which is of the form groups=NUMBER(name),NUMBER(name), etc. So my approach to this is to first jettison the uid and gid values. That looks like this:
id | cut -d\ -f3
The '-d' flag to cut specifies the delimiter that separates fields, then '-f3' says we're only interested in the third field, the group list.
When run, it produces something like this:
groups=20(staff),401(com.apple.access_screensharing),404(com.apple.sharepoint.group.3), 402(com.apple.sharepoint.group.1),403(com.apple.sharepoint.group.2),12(everyone),33(_appstore),61(localaccounts), 79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),100(_lpoperator),204(_developer)
To break it up further, I'm going to use 'tr' to translate all open parens into carriage returns, essentially turning this one long line into a lot of very short lines:
$ id | cut -d\ -f3 | tr '(' '\n'
Two things left: we need to remove everything after the closing paren (which we can do with another invocation of the 'cut' command) and we need to remove the groups=20 line at the very beginning. String it all together and here's what we have:
$ id | cut -d\ -f3 | tr '(' '\n' | cut -d\) -f1 | grep -v '='
With that done, the rest is a breeze, we just wrap it with a 'for' loop:
for groupname in $(id | cut -d\ -f3 | tr '(' '\n' | cut -d\) -f1 | grep -v '=' )
if [ ! -d $groupname ] ; then
That's your code snippet. In my case, it'd be easy to add a filter that would, for example, skip any groupname that started with an underscore or contained a dot, but I'll leave that as an exercise for the reader.
More Useful Shell Script Programming Articles:
✔ Secretly capture screenshots on my Mac?
When I used to work on a Linux system, there was a utility we had that would let me take screen captures every...✔ Parsing "id" strings in a Shell Script?
Hello Dave. I need a Bash shell script that creates a directories with the group names automatically when user logs in to the...✔ Copy and Paste from the Mac OS X Command Line?
I am constantly running commands in Terminal.app on my MacBook and then copying and pasting the results into email messages or documents. Yes,...✔ Script to test line lengths for Twitter compatibility?
I've been tasked with writing a series of tweets for a Black Friday marketing campaign and am finding it a bit tricky because...✔ Shell script to convert lowercase to title case?
As part of a project I'm working on, I find myself deep in a Linux shell script, needing to have a subroutine that...
Let's stay in touch!
Sign up for my weekly AskDaveTaylor Newsletter and you'll receive even more tech and gadget help right to your inbox, along with exclusive news and industry updates. It's good stuff. I promise!
Check This Out Too...
Look for Answers
All Our Categories
Apple iPad Help
Articles and Reviews
Auctions and Online Shopping
Blogs and Blogging
Building Web Site Traffic
Business and Management
Computer and Internet Basics
d) None of the Above
Google Gmail Help
Google Plus Help
Industry News and Trade Shows
iPhone and Cell Phone Help
iPod, Sony PSP and MP3 Player Help
Kindle Fire Help
Mac OS X Help
Pay Per Click (PPC) Advertising
Search Engine Optimization (SEO)
Shell Script Programming
Tech Support Video Help
The Writing Business
Twitter, LinkedIn and Social Network Help
Unix and Linux Help
Video Game Tips and Help
Windows PC Help
Find Me on Google+
ADT on G+