2014-02-20 8 views
0

Я довольно новичок в Linux и сценариях оболочки.WHILE loop not looping

Проблема заключается в том, что скрипт должен читать 2 токена из файла, называемого «список», - используя эти токены, он создает пользователя и в зависимости от второго токена - подпапки. Он делает это просто отлично, но только один раз. Только один раз. Есть ли проблема с моей петлей WHILE?

Вот несколько образцов строк из "списка":

egyes n 
kettes y 
harmas y 

Вот сценарий:

#!/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 

Спасибо заранее.

+1

что-то есть в stdin? –

+0

примечание: сохранение паролей в виде простого текста - плохая идея ... –

+0

это для временного использования, пока я не отправлю их. После этого я удаляю файл, но это не главное. Что значит «есть стдин»? – LZozzy

ответ

2

переход от

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

в

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

Нет, не решил. – LZozzy

+0

Необходимо, но решает другую проблему. – chepner

0

Как указано в комментариях, некоторые команды в цикле читает со стандартного ввода. Вы можете выяснить, какую команду, которая есть, и перенаправить стандартный ввод из /dev/null:

bad_command < /dev/null 

или просто использовать другой дескриптор файл для времени цикла:

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

Теперь команда read не чтение из стандартного ввода, но из дескриптора файла 3, который вряд ли будет использоваться какой-либо командой в теле цикла.


Как отметили BMW, вам нужно исправить if заявления:

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

Пространство вокруг знака равенства необходимо, так как [ это команда, а не часть синтаксиса if, и это требует 3 различных аргументов ($rr, = и "y"); он не будет анализировать одну строку $rr="y" в качестве сравнения. = является предпочтительным с помощью команды [, так как обычно == не является оператором сравнения равенства POSIX. Однако bash действительно позволяет ==, но и обеспечивает превосходную команду, которая не требует $rr котироваться в соответствии с требований по безопасности с [:

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

Вы можете сэкономить набрав в последнем разделе вашего цикла путем объединения echo заявления в одну команду соединения и перенаправление их комбинированного вывода сразу:

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

Другой вариант как указал tripleee, требует ONL y один звонок до cat. Он порождает внешний процесс, но выглядит более чистым.

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

Вы также можете просто echo и одну строку с вложенными символами новой строки.

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

Боль в «эхе» также будет устранена благодаря использованию здесь документа. – tripleee