Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have been trying to write a command (Solaris server) that adds a user to a specific group. It's a pretty long command so I'll post the whole command here and then break it down.

USER=myUser && sudo /usr/sbin/usermod -G `awk -v delim="," -F: '/[:,]'$USER'/ { groups = groups $1 delim; } END { groups = groups "myGroup"; print groups}' /etc/group` myUser

The inner awk command compiles a comma-delimited list of current groups and the outer command takes this list in the -G parameter.

Both awk and usermod are giving me syntax errors (near line 1, but there's only one line), but I have a feeling one error is caused by the other.

Are there any glaring syntax errors here that I'm missing? Could this be caused by a shell issue? As a disclaimer, I am using the && construct instead of a semicolon due to some higher-level text processing issues but that should not affect the execution, in my opinion (I have tested it).

share|improve this question
Rather than asking us to fix your broken code, it would be best to give sample input and desired output. It is highly likely that the best answer may not be the way you're trying to do it. – SiegeX Jan 26 '12 at 22:49
I should've explained more clearly in my question that I am absolutely bound to using this pattern due to its use in a larger application. Also, I described the input and output if you read the post carefully: "The inner awk command compiles a comma-delimited list of current groups and the outer usermod command takes this list in the -G paramter." Given this information, I expect the usermod command to work as anyone would expect given those parameters. – Mark Jan 27 '12 at 15:01
up vote 2 down vote accepted

awk works differently on Solaris – the version available in /usr/bin does not support the -v option. Use nawk for a more POSIX-like version.

The second problem is that, as you already noticed, there's only one line. Do not try to write one-liners if not absolutely necessary; readable commands are easier to fix. If you have to put the command in a config file somewhere – put it in a .sh script instead.

Do not use $USER as a temporary variable; many programs expect this particular variable to contain your login name. Choose something like $user instead.

Do not parse /etc/group when there are tools which do it for you, such as groups. (In addition to making code simpler, they also work with non-local accounts.)

oldgroups=$(groups "$user" | sed "y/ /,/")
usermod -G "$oldgroups,$group" "$user"

or if you insist

user=myUser && sudo usermod -G "$(groups "$user" | sed "y/ /,/"),myGroup" "$user"
share|improve this answer
I appreciate your attempt at a more efficient script and believe me, I would use one if I could, but the way this particular application works, I am bound to using one line commands. It's ugly, but I have no choice. – Mark Jan 27 '12 at 15:08
@Mark: /usr/local/bin/ is a one-line command as well :) Anyway, I did include a one-line version which you could use, at the very bottom of my post. – grawity Jan 27 '12 at 16:04
Yes, it has provided a good basis. It is hard to describe in one post how utterly restricted the execution environment is, but basically this command runs on hundreds of servers, and I cannot copy the script to all of them, so I have to use the known commonalities of each server. – Mark Jan 27 '12 at 16:43

You must log in to answer this question.

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