0

一連のフォルダー/ファイルをバックアップするための bash スクリプトがあります。スクリプトは、事前構成されたファイルをループして、フォルダー/ファイルをコピーする方法を決定します。

私が直面している問題は、スクリプトが最初の「ファイル」エントリ (2 列目の値) を処理した後に 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.
4

2 に答える 2

3

あなたが与えたコマンドが標準入力を使用していなくても、ループ内の呼び出しsshは標準入力から読み取ります。-n次のオプションを使用します。

ssh -n 172.29.32.246 mkdir -p $TARGETDIR$dir

からの標準入力をリダイレクトし/dev/nullます。

于 2013-04-19T00:16:56.663 に答える
1

ループ内の何か (ほぼ確実ssh) が、最初のループ中にファイルの残りを読み取っています。sshの入力を (< /dev/nullまたはそのオプションを使用して)リダイレクトでき-nますが、ループ内の他の何かが stdin から読み取られる可能性がわずかにあります (stdinからパスワードを読み取ろうとすることはないと思いますが、間違っている可能性があります)。 scp

このような場合に私がやりたいことは、readstdin 以外の方法でファイルの内容をコマンドに渡すことです。これにはファイル記述子 #3 を使用する傾向があります。これは、他の目的で使用されることはほとんどないためです。したがって、ループ内の何かがそれを台無しにする可能性はほとんどありません。これを行う3<filenameには、ファイルを fd3 に送り、そこread -u3から読み取るだけです。

while read -u3 dir type args
do
    echo "Processing [$dir $type $args]"
    ...
done 3<$BACKUPLIST
于 2013-04-19T05:37:59.540 に答える