より良い方法

より良い方法

クリーニング時に.bakファイルを生成する簡単なコードがあります。再クリーンアップすると、bak ファイルが削除され、.bak ファイルがなくなります。 bak "no .bak"を表示する必要がありますが、if条件のみを実行します。コードは次のとおりです。

#!/bin/bash
chmod u+x sources/*
if [ "$1" == "clean" ]
then

    if [ -f `sources/*.bak` ]
    then        
       rm sources/*.bak

    else
        echo "there's no .bak files"
    fi

elif ["" == "$1"]
then

echo "This script makes a backup for each .c or .h file in sources directory"

target_files=`echo -n $(ls sources/{*.c,*.h})`
echo
echo "Starting to backup: $target_files"

for i in $target_files 
do 
  cp "$i" "$i".bak
done

echo
echo "The following backup files were created: `echo -n $(ls sources/*.bak)`"
echo
echo "Done"

fi 

答え1

問題はラインです

if [ -f `sources/*.bak` ]

バックティックは`bashで特別な意味を持ちます。これは、コマンドを評価してその出力を返すために使用されます。

たとえば、ユーザー名が次のような場合プロそれから

if [ -f `whoami` ]

という存在があることを確認してくださいfrodl

したがって、を書くと、sources/*.bak最初に用語をglobしようとしますが、sources/*.bakディレクトリに拡張子を持つファイルがないため、用語は拡張されません。次に、有効なコマンドではなくリテラル用語を実行しようとします(実際にはsources/.baksources/*.bakできる(最初にアスタリスクがあるファイル名; shudder!)というファイルがありますがsources/*.bak、ないようです。ただし、このファイルには.bak以前に除外した拡張子があります。 )

ファイルが存在する場合は、sources/deletemyharddisk.bak用語をsources/*.bakその文字列に展開してから実行しようとします(ハードドライブが消去される可能性があります)。

したがって、やるべきことは一般的な引用符を使用することだけです。

backupfiles=sources/*.bak
if [ "x${backupfiles}" = "xsources/*.bak" ]; then
     echo "no .bak files" 1>&2
else
     echo "there are .bak files"...
fi

まず、用語を変数sources/*.bakに拡張しようとします。backupfilesbakファイルがある場合は、すべてのファイル名の文字列になります。ファイルが存在しない場合、文字列は拡張されていません。次に、結果をリテラル(拡張されていない)と比較すると、一致するファイルがあるためにsources/*.bak拡張が発生したかどうかがわかります。

より良い方法

しかし、最初にファイルが存在することを確認してから削除する理由はありません。より簡単なアプローチは、特定のパターンに一致するすべてのファイルを削除することです。 findあなたのためにこれを行うことができます:

find sources/ -maxdepth 1 -type f -name "*.bak" -delete

-maxdepth 1(これを行うと、ディレクトリ()の最初のレベルでsources/()で終わるファイルを検索します(-type f;ディレクトリやシンボリックリンクなどではありません)。その後、そのファイルを削除します()。.bak-name "*.bak"-delete

解析されないls

コードのもう一つの問題は

target_files=`echo -n $(ls sources/{*.c,*.h})`
for i in $target_files 
...

あなたはする必要があります解析されない出力ls

代わりに、次のようなものを使用してください。

 for i in sources/*.c sources/*h
 do
   #...
 done

関連情報