web-dev-qa-db-ja.com

bashスクリプトのrmコマンドが変数で機能しない

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

そこで、保守性を考慮して変数を使用してスクリプトを作成します。

スクリプト全体が実際に機能していますが、機能しないのは古いスクリプトを削除することだけです。それが一番簡単だと思っていました。

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

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

2つ目は、シェルコマンドで "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

ありがとうございました、

5
vekah

別の方法は、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はすべてのサブディレクトリを検索します。 maxdepthオプションを使用して、必要に応じて検索操作を現在のディレクトリに制限できます。

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

Rmと変数を使い続ける必要がある場合、これは1行でうまくいきました。

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
1
George Vasiliou

rm "$OUTPUT/*.gz"

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

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

rmを開始すると、その/path/to/backup/files/*.gzファイルを削除しようとします。そのファイルが存在しない場合(あなたの場合と同様)、エラーが報告されます。

あなたが書くとき:

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

または

rm "$OUTPUT"/*.gz

今回は*が引用されていないため、グロビング、ファイル名生成、またはファイル名拡張と呼ばれる、シェルの別の特別な機能がトリガーされます。シェルは、その*文字を含むWordを、パターンに一致するファイル名のリストに展開しようとします。

したがって、/path/to/backup/filesa.gzおよびb.gzファイルが含まれている場合、シェルは実際にrmを、rm/path/to/backup/files/a.gz、および/path/to/backup/files/b.gzの3つの引数で呼び出します。

$OUTPUT自体は引用符で囲む必要があることに注意してください。そうしないと、$IFSの文字が含まれている場合は分割されたり、ワイルドカード文字(上記の*など)が含まれている場合はグロブの対象になる可能性があります。

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

rm -- "$OUTPUT"/*.gz

ここで$OUTPUT/で始まっているので問題ありませんが、たとえば$OUTPUT-foo-に変更すると、-foo-/...rmによってオプションとして取得されるため、動作が停止します。

スクリプトがインタラクティブである必要がない場合は、-fオプションをrmに追加することができます。これにより、すべてのユーザープロンプトが無効になり、一致するファイルがない場合はエラーが削除されます(ほとんどのシェル、グロブが一致しない場合、パターンはそのままアプリケーションに渡され、rm -fは、そもそも存在しません)。

11