青少年MMV

青少年MMV

$sh s3.shへのバックアップ

backup-to-s3.sh: 11: [: bkup_20151106_150532.zip: unexpected operator
backup-to-s3.sh: 11: [: bkup_20151106_150532.zip: unexpected operator
backup-to-s3.sh: 11: [: bkup_20151106_150532.zip: unexpected operator
backup-to-s3.sh: 11: [: bkup_20151106_150532.zip: unexpected operator
backup-to-s3.sh: 11: [: bkup_20151106_150532.zip: unexpected operator
backup-to-s3.sh: 11: [: bkup_20151106_150532.zip: unexpected operator

ubuntu@accretive-staging-32gb-ephemeral:~$ cat backup-to-s3.sh

#Script to move /home/ubuntu/backup folder  to S3://auto-backup
#Author Ashish Karpe
cd /mnt/backup
filename="bkup_$(date +%Y%m%d_)"
/bin/ls -alF | awk '{ print $9 }'  > /tmp/file

for i in $(cat /tmp/file); do
#       echo $i;
#       read a;
#       echo $filename;
        if [ $filename* = $i ]
        then
                echo "Copying " $i "to S3://auto-backup";
                s3cmd put $i s3://auto-backup

            fi

done

答え1

  1. forファイルの行を繰り返すために使用しないでください。

    while IFS= read -r line; do ...; done < filename
    
  2. ls出力をファイルにパイプする必要はありません。特に使用-F

  3. bashを使用した[[ x == y ]]パターン比較、右パターン:
#!/bin/bash
cd /mnt/backup
prefix="bkup_$(date +%Y%m%d_)"

for file in * .*; do
    [[ -f $file ]] || continue    # skip things like directories and soft links
    if [[ $file == $prefix* ]]; then
        echo "Copying " $file "to S3://auto-backup";
        s3cmd put $file s3://auto-backup
    fi
done < /tmp/file

答え2

「ls」の出力をファイルにダンプして解析しても、「ls」の出力を間接的に解析することです。これは問題があるか、非常に悪い考えか、完全に間違っています!誰に尋ねるかによって異なります。

これは'ls'の出力を解析しない理由

これはシェルのファイル名とパス名:正しく取得する方法

たとえば、ファイル名に "-"(ダッシュ/ハイフン)があり、エスケープされていない場合(前にバックスラッシュ( "\")を追加して)、パラメータとして解釈できます。

「ls」の解析を避けることは、次のように簡単です。

find . -maxdepth 1 -iname "*"
.
./dont_parse_ls.sh
./array.dat
./.bashrc
./BASH.Indirect.Reference.sh
./basharray.sh
./.forever

結果は同じ

/bin/ls -alF | awk '{ print $9 }'

./
../
.bashrc
.forever/
BASH.Indirect.Reference.sh
array.dat
basharray.sh*
dont_parse_ls.sh

青少年MMV

答え3

スクリプトには少なくとも2つの主な問題があります。基本的な問題は彫刻です。

if [ $filename* =

これにはいくつかの問題があります。まず、シェルスクリプトでは、一致するパターンを「ワイルドカード」として指定することはできません。もちろん、これはできますが、fileglobが複数の一致を生成する場合は同時にすべて取得できます。この場合、「[」プログラム(例:プログラム)は次のことを評価しようとします。

filename1 filename2 filename3 = $i

fileglobが正確にファイル名に拡張されている場合にのみ機能しますが、これを保証することはできません。あなたの場合、$ filenameは少なくとも1つのファイルに拡張されますが、必ずしもそうではないことに注意してください。 "$file*" このファイルがまったくないように拡張された場合 (shopt の設定に応じて) 空の文字列を取得できます。

= $i

これにより[故障が発生します。しかし、正しい店舗を利用すると、次のような利点が得られます。

backup-2014-whatever* = $i

*比較の一環として。

2番目の基本的な問題は-Fパラメータの使用ですls。これは、ファイルが実行可能ファイルであるかソフトリンクであるかに応じて、ファイル名に複数の文字のいずれかを追加するようにlsに指示します。

NetScr1beは意味がありますが、NetScr1beのアドバイスに従う必要はなく、絶対に使用しないでくださいls。ただ使用しないでくださいls -l。代わりに、ls -1これを使用すると、ファイル名は装飾なしで単一の列に印刷されます。 (非常に大きなディレクトリの場合はソートするので問題になる可能性があります。この場合はソートされていないオプションがあります。代わりにfindを使用してください。)

より安全にするには、変数を二重引用符で囲み、LHSとRHSの両方の前にダミー文字を付けて、aで始まる奇妙なファイル名が-失われないようにする必要があります。

私はGlennのアドバイスをある程度受け入れてこれを行います。

command ls -1 | while read file; do
    if [ x"$file" = x"$filename" ]]; then 
        echo Do Work Here
    fi
done

私はこれです会議ところで、グレンは親切に必ずしなければならないと言いました。彼の方法:

for file in *; do 
    if [[ $file == $filename ]]; then ...

答え4

このスクリプトはすべてのタスクを実行します。なぜできないのですか?シェルは正しいファイルを選択するので、次のものを呼び出す必要はありませんls

#!/bin/sh
for file in /mnt/backup/bkup_$(date +%Y%m%d)_*
do
    s3cmd put "$file" s3://auto-backup
done
  • 唯一の外部コマンドはですs3cmd
  • 氏名がありませんif
  • 唯一の決定点はforループです。
  • 読みやすい。

関連情報