4

I have written a shell script which allows me to create a user and assign them to a group but I keep getting the error line 19: syntax error: unexpected end to file

What am I doing wrong? Would it be possible someone could help me re structure the code to eliminate this problem.

Here is my shell script.

#!/bin/bash
username="U"
group="G"
while [ $username"U" ] >/dev/null 2>&1;
read -p "Please input the username you would like to generate"
if
  id -U $username >/dev/null 2&1;
echo 'User already exists"
while [ $group >dev/null 2>&1; 

echo "group exists"

else
    groupadd $group
fi
StrongBad
  • 5,261
  • 1
    Dear Poster, Please put your code into edit page and select it, Then press CTRL+K. – PersianGulf Mar 22 '16 at 20:46
  • Please dont post screenshots of text, paste the actual text... – jasonwryan Mar 22 '16 at 20:46
  • 1
    Your while [ condition ]; do... statements need closure with done. if [ condition ] statement needs to be flowed by then keyword. It is not implied. – MelBurslan Mar 22 '16 at 20:46
  • Put the script in here, surrounded by lines containing three backticks like ```. – Henrik supports the community Mar 22 '16 at 20:47
  • The indentation of your code is awful. Proper indentation would make it a lot easier to see what is wrong, but @MelBurslan has a lot of it. – Henrik supports the community Mar 22 '16 at 20:50
  • what are you trying to accomplish with this script ? Can you briefly explain in words ? It sounds like you are trying to create usernames, which were input from the keyboard and check if they already exist. If not create them. Is this the gist of it ? Or there is something else to it ? If it is, your logic is not correct, as well as your use of bash syntax leaves a lot to be desired. Although I have to give it to you at least for trying, unlike too many people here expecting someone else do all the work. – MelBurslan Mar 22 '16 at 21:11
  • Thanks, I appreciate this. My task is to write a script that creates new users and assigning them to groups. – Programmer Mar 22 '16 at 21:17
  • Do you want your script to take username and groups as arguments? Or to ask the user for input? – L. Levrel Mar 22 '16 at 21:30
  • Ask the user to input also I'm not fimilar what you mean by arguments. – Programmer Mar 22 '16 at 21:39
  • Hint: look at the colors in your question. Tip: use an editor with syntax-based coloring. – Gilles 'SO- stop being evil' Mar 22 '16 at 21:45
  • Arguments are specified on the command line itself, not prompted and asked for by the script. In your case, you might use ./myscript username groupname and then in your script use "$1" for the username and "$2" for the group name. Note the use of double-quotes around the $1 and $2 variables. it's good practice to (almost) always quote your variables (except in certain special cases which there's no need to go into now), especially if the variable's value is provided by a user in any way (e.g. via command-line args or prompted input). – cas Mar 23 '16 at 02:27

2 Answers2

1

This is something you could use. It will remain in the loop until a new non existing user has been created.

#!/usr/bin/env bash

anotherUser() {
   read -p "Add another user? [y/n]" yn
   if [[ $yn = *[yY]* ]]; then
      checkUser
   fi
   exit
}
checkUser() {
while :
   do
      read -p "Enter user: " userName
      if id $userName >/dev/null
         then echo "User exists"
         anotherUser
      else
         adduser "$userName"
         printf "User %s has been added\n" "$userName"
         exit
      fi
   done
}
checkUser
  • This is perfect, thanks for taking the time to help me out. Instead of it keep looping would it be possible if you could add something like do you want to create another user y/n and if the user inputs n it will terminate. – Programmer Mar 22 '16 at 21:51
  • I have updated my answer. I haven't built any checking though, but that's left as exercise for the student! ;) – Valentin Bajrami Mar 22 '16 at 22:02
  • Thanks, what do you mean by checking? Do you mean running the script and seeing if it executes? – Programmer Mar 22 '16 at 22:07
  • I mean the user input. You never know if a user will put a _ or a <-- space etc. Anyways, you now should have a bit of an idea of what this script does. – Valentin Bajrami Mar 22 '16 at 22:10
  • Oh right. For example I should include something like if user inputs integer ask the question again. – Programmer Mar 22 '16 at 22:15
  • @L.Docherty correct. Integers in usernames on *nix are allowed though but they may not start with an integer. E.g 12345 as a username is not allowed where abc1234 is allowed. You just run the script, test it a bit and modify it to your needs. – Valentin Bajrami Mar 22 '16 at 22:19
  • '#!/usr/bin/env bash' Quick question why did you use env bash? – Programmer Mar 22 '16 at 22:40
  • @L.Docherty this makes sure that the script looks at whatever shell is availiable on your path. It is more portable. If you are running a recent version of ubuntu or fedora or any other distribution, #!/bin/bash would work as well. – Valentin Bajrami Mar 22 '16 at 22:52
  • I got another error. The first one is line 19: unexpected E0F while looking for match and line 26 syntax error unexpected end of file. – Programmer Mar 22 '16 at 23:07
  • More accurately, #!/usr/bin/env bash is a dreadful mistake promoted by the python and ruby communities because they don't care that it breaks the ability to pass command-line options to the interpreter, or that it doesn't fix the rare problem of not knowing the exact path of the interpreter (bash or whatever), it just shifts the problem to not knowing the exact path of env, and causes other problems. See http://unix.stackexchange.com/questions/29608/why-is-it-better-to-use-usr-bin-env-name-instead-of-path-to-name-as-my for arguments for and against using env on the #! line of a script – cas Mar 23 '16 at 02:37
0

You have to change via $? variable. It stores the return value of last command:

id -u $username > /dev/null 2>&1 ;
if [[ "$?" -eq 0 ]]; then
        echo "username already exists."

If it equals 1, it doesn't exist.
BTW, your blocks are very dirty.... Use the following link:
Indentation (typesetting)
Also close your blocks.

MelBurslan
  • 6,966
PersianGulf
  • 10,850
  • Yes I'm aware of the indentations being poor but I'm trying my best. I have visited the hyperlink webpage but since I'm new at this I'm still very confused. Would you mind making some adjustments and pointing me in the right direction with my code please? – Programmer Mar 22 '16 at 21:25
  • @PersianGulf: you don't have to do this I think. if id -u $username >/dev/null 2>&1; then should work. – L. Levrel Mar 22 '16 at 21:34
  • @L. Levrel , I didn't use id command in if statement, please reread my code. – PersianGulf Mar 22 '16 at 21:53
  • @L.Docherty , You can use Advanced bash script by TLDP : http://www.tldp.org/LDP/abs/html/ ,Even you can download it's pdf from tldp.org – PersianGulf Mar 22 '16 at 21:55
  • I appreciate the feedback, I will read this now. – Programmer Mar 22 '16 at 22:04
  • @PersianGulf: That's exactly what I mean. IMHO it is simpler to put the command in the if statement. YMMV – L. Levrel Mar 23 '16 at 21:17
  • 1
    @L.Docherty reality sorry, I think I answered you via bashism. – PersianGulf Mar 24 '16 at 00:04
  • @PersianGulf No problem, could you help me with this please? http://unix.stackexchange.com/questions/271809/shell-script-creating-and-assign-to-groups-advice-needed-on-my-script. – Programmer Mar 24 '16 at 00:09