0

I'm fairly new to Linux and shell scripting.

My problem is, that the script should read 2 tokens from a file called "list" - using these tokens, it creates a user and depending on the second token, a sub folder. It does this just fine - but only once. Only ONCE. Is there a problem with my WHILE loop?

Here is a few sample lines from "list":

egyes n
kettes y
harmas y

Here's the script:

#!/bin/bash
echo " " >> /root/userpass.txt
most=$(date)

while read user rr; do
    p1=${user:0:2}
    p2=${user:3:4}
    pass=$p1$RANDOM$p2
    echo $user - $pass --" LÉTREHOZVA: "$most >> /root/userpass.txt

    adduser $user > /dev/null
    echo $user:$pass | chpasswd > /dev/null

    uhome=/home/$user

    if [ $rr=="y" ]; then
            mkdir $uhome/rockandroll
            chown $user $uhome/rockandroll
    fi

    mkdir $uhome/res-devres
    chown $user $uhome/res-devres

    ftpc=/etc/proftpd/proftpd.conf

    echo "#"$1 >> $ftpc
    echo "<Directory "$uhome"/res-devres/>" >> $ftpc
    echo '  <Limit CDUP XCUP STOR LIST CWD XCWD STOU>' >> $ftpc
    echo '          AllowAll' >> $ftpc
    echo '  </Limit>' >> $ftpc
    echo '  <Limit RETR DELE>' >> $ftpc
    echo '          DenyAll' >> $ftpc
    echo '  </Limit>' >> $ftpc
    echo '</Directory>' >> $ftpc
    echo " " >> $ftpc
    echo " "
done < list

Thanks in advance.

5
  • 1
    something eating the stdin? Commented Feb 20, 2014 at 11:01
  • note: storing passwords as plain text is a bad idea... Commented Feb 20, 2014 at 11:02
  • it is for temporary use, just until I send them out. After that I delete the file, but that's not the point. what do you mean "eating the stdin"? Commented Feb 20, 2014 at 11:09
  • 1
    any process that's reading from stdin will process the input of your loop. you can find it with simple elimination.. Commented Feb 20, 2014 at 11:09
  • Yeah, probably that's the one - how can I stop it from accessing stdin after doing it's job? Commented Feb 20, 2014 at 14:03

2 Answers 2

3

change from

if [ $rr=="y" ]; then

to

if [ $rr == "y" ]; then
Sign up to request clarification or add additional context in comments.

Comments

0

As pointed out in the comments, some command in your loop is reading from standard input. You can either figure out which command that is, and redirect its standard input from /dev/null:

bad_command < /dev/null

or simply use a different file descriptor for the while loop:

while read user rr <&3; do
    ...
done 3< list

Now the read command is not reading from standard input, but from file descriptor 3, which is unlikely to be in use by any command in the body of the loop.


As pointed out by BMW, you need to fix your if statement:

if [ "$rr" = "y" ]; then

The spaces around the equal sign are necessary, as [ is a command, not part of the if syntax, and it requires 3 distinct arguments ($rr, =, and "y"); it will not parse the single string $rr="y" as a comparison. = is preferred with the [ command, as generally == is not the POSIX equality comparison operator. However, bash does allow ==, but also provides a superior command which does not require $rr to be quoted as required for safety with [:

if [[ $rr == y ]]; then    # == or = will work the same

You can save some typing in the last section of your loop by combining the echo statements into a single compound command and redirecting their combined output once:

{
    echo ...
    echo ...
    echo ...
} > "$ftpc"

Another option as pointed out by tripleee, requires only a single call to cat. It spawns an external process, but looks cleaner.

cat > "$ftpc" <<EOF
#$1
<Directory $uhome/res-devres/>
etc
EOF

You could also just echo and a single string with embedded newlines.

echo "#$1
<Directory $uhome/res-devres/>
etc
" > "$ftpc"

1 Comment

The echo pain would be alleviated by the use of a here document, too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.