2013-04-18 48 views
0

我有一個用於備份一組文件夾/文件的bash腳本。該腳本通過預先配置的文件循環以確定如何複製文件夾/文件。Bash腳本無法讀取整個文件

我面臨的問題是腳本在處理第一個「文件」條目(第二列值)後退出while循環。

這是腳本。

#!/bin/bash 

sudo crontab -l > /home/ipaccess/crontab.txt 

DATE=`date +%m-%d-%Y` 

TARGETDIR="/exports/backup/Web-Server/$DATE/" 
BACKUPLIST="/home/ipaccess/backup/backuplist" 
ssh 172.29.32.246 mkdir -p $TARGETDIR 
scp -r /home/ipaccess/crontab.txt 172.29.32.246:$TARGETDIR 

cat $BACKUPLIST 

while read dir type args 
do 
    echo "Processing [$dir $type $args]" 
    echo "Directory: $dir" 
    echo "Element type: $type" 

    if [ $type = "folder" ] ; then 
     echo "Source: $args" 
     echo "Transfering $args to 172.29.32.246:$TARGETDIR$dir" 
     scp -r $args 172.29.32.246:$TARGETDIR 
    fi 
    if [ $type = "file" ] ; then 
     # Create folders first 
     echo "Creating $TARGETDIR$dir" 
     ssh 172.29.32.246 mkdir -p $TARGETDIR$dir 
     scp $args 172.29.32.246:$TARGETDIR$dir 
    fi 
    echo "Finished processing $dir $type $args" 
    echo "Next entry.." 
done<$BACKUPLIST 
echo "Backup complete." 

這裏是預先配置的文件(backuplist)

html/GS folder /var/www/html/GS/css 
html/GS folder /var/www/html/GS/images 
html/GS file /var/www/html/GS/*.html 
html/GS file /var/www/html/GS/*.inc 
html/GS file /var/www/html/GS/*.png 
html/GS file /var/www/html/GS/*.mysql 
html/GS file /var/www/html/GS/ac-db 
html/HC file /var/www/html/HC/*.php 
html/HC file /var/www/html/HC/*.html 
html/HC file /var/www/html/HC/images 
html/HC file /var/www/html/HC/PM/*.php 
html/HC/PM file /var/www/html/HC/PM/jsapi 
html/HourlyKpi file /var/www/html/HourlyKpi/*.php 
html/KPI folder /var/www/html/KPI 
html/KpiQuery folder /var/www/html/KpiQuery 
html/wordpress/ folder /var/www/html/wordpress 
usr/local/apache2/conf file /usr/local/apache2/conf/httpd.conf 
cgi-bin folder /var/www/cgi-bin 
html/GS file /var/www/html/GS/*.php 

這裏是腳本

Processing [html/GS file /var/www/html/GS/*.html] 
+ echo 'Directory: html/GS' 
Directory: html/GS 
+ echo 'Element type: file' 
Element type: file 
+ '[' file = folder ']' 
+ '[' file = file ']' 
+ echo 'Creating /exports/backup/Web-Server/04-18-2013/html/GS' 
Creating /exports/backup/Web-Server/04-18-2013/html/GS 
+ ssh 172.29.32.246 mkdir -p /exports/backup/Web-Server/04-18-2013/html/GS 
+ scp /var/www/html/GS/gs.html /var/www/html/GS/login_header.html /var/www/html/GS/nologin_header.html /var/www/html/GS/overlaynal.html /var/www/html/GS/tab-test.html 172.29.32.246:/exports/backup/Web-Server/04-18-2013/html/GS 
gs.html                       100% 3204  3.1KB/s 00:0 
login_header.html                     100% 418  0.4KB/s 00:0 
nologin_header.html                    100% 464  0.5KB/s 00:0 
overlay-external.html                    100% 2308  2.3KB/s 00:0 
tab-test.html                      100% 1573  1.5KB/s 00:0 
+ echo 'Finished processing html/GS file /var/www/html/GS/*.html' 
Finished processing html/GS file /var/www/html/GS/*.html 
+ echo 'Next entry..' 
Next entry.. 
+ read dir type args 
+ echo 'Backup complete.' 
Backup complete. 
+2

歡迎堆棧溢出。請儘快閱讀[常見問題]。好的第一個問題。我懷疑循環體內的其中一個命令已經將'$ BACKUPLIST'文件中的其餘行作爲其標準輸入 - 可能是'ssh'命令。沒有保證,但似乎合理。嘗試從'/ dev/null'(和'scp')重定向'ssh'的輸入。 –

+0

在提交我的問題之前,我確實閱讀了FAQ :-)如何將/ ssh的輸入重定向到/ dev/null? –

+0

我懷疑有東西在消耗文件的其餘部分。它可能與正在讀取的文件中的* .html有關? –

回答

2

在循環到ssh呼叫從標準輸入讀取的輸出,即使您給它的命令不使用標準輸入。使用-n選項:

ssh -n 172.29.32.246 mkdir -p $TARGETDIR$dir 

標準輸入從/dev/null重定向。

+0

這解決了這個問題,現在我有一個完整的備份腳本。感謝所有迴應的人。 –

1

循環內的某些東西(幾乎肯定是ssh)正在第一次循環中讀取文件的其餘部分。您可以重定向ssh的輸入(使用< /dev/null或其-n選項),但循環中的其他內容稍微可能會從stdin讀取(我不認爲認爲scp曾嘗試從stdin讀取密碼,但我可能是錯的)。

我喜歡在這種情況下做的事情是通過除stdin以外的東西將文件內容傳遞給read命令。我傾向於使用文件描述符#3,因爲它幾乎不用於其他任何事情,因此很可能循環內部的任何內容都不會混淆它。要做到這一點,只需使用3<filename到文件喂FD3,並read -u3從中讀取:

while read -u3 dir type args 
do 
    echo "Processing [$dir $type $args]" 
    ... 
done 3<$BACKUPLIST 
+0

+1良好的通用解決方案;這是我會發布的答案,但我感覺很懶,最近提醒''n'選項改爲'ssh'。 – chepner

+0

另一種解決方案也很好,謝謝。 –