Bashスクリプトのrmコマンドは変数と連携しません

Bashスクリプトのrmコマンドは変数と連携しません

mysqlデータベースのバックアップを作成するためのbashスクリプトを作成しています。実際には古いものを削除したいです。

したがって、メンテナンスのために変数を使用してスクリプトを作成します。

スクリプト全体が実際に動作しているが動作しない唯一のことは、古いスクリプトを削除することです。私はこれが簡単な部分だと思いました。

とにかく、これは私のコードです。誰が問題があるのか​​教えてもらえますか? rm コマンドは以下を返しますrm: impossible de supprimer « /path/to/backup/files/*.gz »: Aucun fichier ou dossier de ce typerm: impossible to delete « /path/to/backup/files/*.gz »: no files or directory of this type

しかし、本当に奇妙なことはまずチュートリアルでこのスクリプトを見つけました。

次に、シェルコマンドで「rm /path/to/backup/files/*.gz」を実行すると、期待どおりにすべての.gzファイルが機能して削除されます。

#!/bin/bash

USER="***"
PASSWORD="****"
OUTPUT="/path/to/backup/files"

rm "$OUTPUT/*.gz"

databases=`mysql --user=$USER --password=$PASSWORD -e "SHOW DATABASES;" | tr -d "| " | grep -v Database`

for db in $databases; do
    if [[ "$db" != "information_schema" ]] && [[ "$db" != _* ]] && [[ "$db" != "performance_schema" ]] ; then
        echo "Dumping database: $db"
        mysqldump --force --opt --user=$USER --password=$PASSWORD --databases $db > $OUTPUT/`date +%Y%m%d`.$db.sql
        gzip $OUTPUT/`date +%Y%m%d`.$db.sql
    fi
done

ありがとう、

答え1

これ

rm "$OUTPUT/*.gz"

シェルコマンドラインは、シェルに2つの引数(および/bin/rm)を使用して実行するように指示します。rm/path/to/backup/files/*.gz

スペース"$シェル言語構文の特殊文字です。スペースはコマンド引数を区別し、上記のような他の特殊文字(すべてではなく、まだ特殊文字)を引用し、"いくつかの拡張(たとえば、ここで使用するパラメータ拡張)に使用されます。$*$$OUTPUT

rm起動後にファイルを削除しようとします/path/to/backup/files/*.gz。あなたのようにファイルが存在しない場合は、エラーが報告されます。

あなたが書くとき:

rm /path/to/backup/files/*.gz

または

rm "$OUTPUT"/*.gz

今回は引用されていないため、*ワイルドカード、ファイル名の生成、またはファイル名拡張というシェルの他の特殊機能がトリガーされます。シェルは、*この文字を含む単語をこのパターンに一致するファイル名のリストに拡張しようとします。

したがって、aとファイルを/path/to/backup/files含めると、シェルは実際に必要なものに似た3つの引数で呼び出されます。a.gzb.gzrmrm/path/to/backup/files/a.gz/path/to/backup/files/b.gz

$OUTPUTそれでも自分で引用する必要があることに注意してください。そうでなければ、文字が含まれている場合は分割され、ワイルド$IFSカードが含まれていると(上記のように)*ワイルドカードの影響を受ける可能性があります。

書くことに慣れるのも良い考えです。

rm -- "$OUTPUT"/*.gz

これは$OUTPUT最初から起こるので/重要ではありませんが、たとえば$OUTPUT変更する日はオプションと見なされ、動作が停止します。-foo--foo-/...rm

-fスクリプトが対話型でない場合は、このオプションをに追加できますrm。これにより、一致するファイルがない場合は、すべてのユーザープロンプトが無効になり、エラーが削除されます。ほとんどのシェルは、globが一致しない場合、パターンをそのままアプリケーションに渡します。rm -fもともと存在しない一致しないファイルを削除するように求められた場合、文句はありません。 )

答え2

別のアプローチは、rmをfindおよび/またはxargsと組み合わせることです。以下はいくつかの選択肢です。

find "$output" -name *.gz -type f -delete
find "$output" -name "*.gz" -type f -exec rm '{}' \;
find "$output" -name *.gz -type f -print0 | xargs -0 rm

PS:ファイルを見つけるにはfと入力してください。

デフォルトでは、findはすべてのサブディレクトリを検索します。必要に応じて、maxlengthオプションを使用して検索操作を現在のディレクトリに制限できます。

find "$output" -maxdepth 1 -name "*.gz" -type f -exec rm '{}' \;

rmと変数を引き続き使用する必要がある場合は、これが私に役立ちました。

out="/home/gv/Desktop/PythonTests/appsfiles";rm "$out"/*.txt
rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/a.txt'? y
rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/a ver 1.txt'? y
rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/b.txt'? y
rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/c.txt'? y
rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/d.txt'? y

答え3

次のファイルをインポートして削除してみてください。

ARCS=`ls $OUTPUT | grep "\.gz$"`

for _arch in $ARCS; do
    rm -f $_arch
done

関連情報