LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (http://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   While script issue, "cannot create directory..." (http://www.linuxquestions.org/questions/linux-newbie-8/while-script-issue-cannot-create-directory-771049/)

Karas 11-23-2009 02:42 PM

While script issue, "cannot create directory..."
 
Hi, me again!

The script below, is probably wrong. However I am learning at the moment. What I am hoping is to make new directories for potential new users, and I would like to copy the /etc/skel folder contents to their home directories, I thought the script below would, however it does not.

I cannot use the adduser command, as this is for a university project, and am only allowed to use the newusers command, and am meant to copy the contents from the /etc/skel folder, however as you can see I am having difficulties.

Any help, would be very much appreciated.

Quote:

#!/bin/bash
PATH=$PATH
names=`cat newusers.txt | cut -f1 -d":"`

while read line
do
mkdir $names
cp -r /etc/skel $name/
done
The error message I recieve after running this script is:

Quote:

mkdir: cannot create directory `gary': File exists
mkdir: cannot create directory `test1': File exists
mkdir: cannot create directory `heat': File exists
mkdir: cannot create directory `omg': File exists
Four folders are created that correspond to each username, but, inside of one folder 3 of the same usernames from the parent directory are created, and inside only one of those is the contents of the /etc/skel directory.

rweaver 11-23-2009 02:46 PM

I'd do it this way (i didn't test this script however):

Code:

for i in `cat newusers.txt | cut -f1 -d":"`; do
  mkdir /home/$i
  cp -R /etc/skel/* /home/$i
done


Karas 11-23-2009 02:56 PM

That script gives me "permission denied" for each folder it tries to make...

Chirel 11-23-2009 03:00 PM

If you also need to create the users that are on the userlist.txt file i'll make the script like that.

Code:


#!/bin/bash
# PATH=$PATH  -- this is useless as you don't change it.

newusers newusers.txt

# there you should test if the job is done by testing $?
# i let you do it.

for i in $(cut -f1 -d":" newusers.txt) ; do

  # cp with -a i prefer.
  cp -a /etc/skel /home/$i

  # i force the owner of the file to the user ($i)
  chown -R $i /home/$i
done

But the real problem for you is that u can't run this script without being root.

So maybe all that is useless because newusers will create the userdir and copy the skel by himself if you have the right to execute it.

I suppose that you are using sudo for that.

Karas 11-23-2009 03:05 PM

Im using a cronjob for root to run all the scripts, I want it to be all automated.

Chirel 11-23-2009 03:22 PM

Quote:

Originally Posted by Karas (Post 3767134)
Im using a cronjob for root to run all the scripts, I want it to be all automated.

So i guess you don't want to run it twice with the same newusers.txt

And if you plan to make a cron job, you should log the process of the script somewhere.

Maybe only with >>/var/log/mylogfile.log at the end of the cronjob call.

But anyways, then you should add some check on the scripts - something like this.

Code:

#!/bin/bash
# PATH=$PATH  -- this is useless as you don't change it.
NEWUSERFILE=/somewhere/over/there/newusers.txt
TMPFILE=/tmp/newusers.txt.tmp

if [ -w $NEWUSERFILE ]
  then
    # we move the file to a temporary working file
    mv $NEWUSERFILE $TMPFILE
  else
    echo "Nothing to do."
    exit 0
fi

newusers $TMPFILE

# there you should test if the job is done by testing $?
# i let you do it.

for i in $(cut -f1 -d":" $TMPFILE) ; do

  # cp with -a i prefer.
  cp -a /etc/skel /home/$i

  # i force the owner of the file to the user ($i)
  chown -R $i /home/$i
done


Now the script will move the working file so a second run will do nothing.

You can't test this script without being root.

To use this script change the NEWUSERFILE to the full path of the newusers.txt file.

Beware of the PATH when using cron job, it's a good idea to add PATH=(a copy of root PATH) at the begining of the script.

i92guboj 11-23-2009 03:25 PM

Code:

#!/bin/bash
PATH=$PATH

That line stores the contents of $PATH in $PATH, resulting in, well, $PATH containing what path $PATH contains. In other words, it does nothing.

Quote:

names=`cat newusers.txt | cut -f1 -d":"`

while read line
The problem here is that you store the names into a variable, but you are not telling "read" from where to actually read them. You could echo the variable and pipe it into the while loop, but that's not the easiest in this case because cut would not provide carriage returns as far as I know. So, I'd use the for sentence provided above by someone else.

You could as well turn $names into an array,

Code:

names=(`cat foo.txt | cut -f1 -d":"`)
for i in $(seq 0 $((${#names}-1))); do
  echo names[$i]=${names[$i]}
done

Quote:

Four folders are created that correspond to each username, but, inside of one folder 3 of the same usernames from the parent directory are created, and inside only one of those is the contents of the /etc/skel directory.
You need to process the directories separately, something that your current loop fails to do. You also need to check if the directory already exists, like in

Code:

if [ -d "/home/${names[i]} ]; then
  echo "directory already exists"
else
  echo "directory doesn't exist,"
  echo "* creating it..."
  echo "* copying skel..."
fi



This is your script:

Code:

#!/bin/bash
PATH=$PATH
names=`cat newusers.txt | cut -f1 -d":"`

while read line
do
mkdir $names
cp -r /etc/skel $name/
done

This stores the names into a var, names will contain something like

Code:

name="foo bar moo cow"
Being each of the tokens the name of one user. The, your while statement reads a string and puts it into a variable called "$line", which by the way you never use in your script, so it serves absolutely no purpose (vars that are never referenced are useless, like a book that's never read).

In any case, after reading a variable from your keyboard, it runs this command

Code:

mkdir $names
With my example above, this would expand to

Code:

mkdir foo bar moo cow
This will create 4 dirs, assuming they do not exist. Where? Well... you didn't even specify, so it will create those 4 dirs wherever you are at the moment, you are creating all the dirs in a row, not a good thing because you don't know the list beforehand by the way, and it might be too long. Never make assumptions like "the list is always gonna fit in a single argument line".

The next command gets even worse:

Code:

cp -R /etc/skel $names/
which would expand to

Code:

cp -R /etc/skel foo bar moo cow/
cp uses the last argument as destination, so this command means textually: "copy recursively all of /etc/skel foo bar AND moo INTO cow/".

Then the while loop starts again, asking you for another name that won't be used for anything, and so ad infinitum.

Karas 11-24-2009 02:30 PM

I've sort of worked out how I am going to be doing the for loops, however I am just wondering, how do I get two variables out of the file newusers, which I can use in the same for loop?

chrism01 11-24-2009 11:19 PM

What does the newusers file look like ie the content?

Chirel 11-25-2009 02:35 PM

Quote:

Originally Posted by Karas (Post 3768237)
I've sort of worked out how I am going to be doing the for loops, however I am just wondering, how do I get two variables out of the file newusers, which I can use in the same for loop?

like that ?
Code:

cat /etc/passwd | { IFS=':'; while read m_name m_pass m_uid m_gid m_rest; do echo "[$m_name $m_uid]"; done }

i92guboj 11-25-2009 03:51 PM

I find it simpler to just read lines, then do all the parsing inside the loop to tokenize the $line.


All times are GMT -5. The time now is 01:36 PM.