2017-12-03 5 views
3

コマンドラインとbashスクリプトから同じコマンドを実行すると、Ubuntu 16.04で異なる結果が生成されます。スクリプトから呼び出されたときに一致するすべてのファイルが返されない

私は、次の内容のフォルダを持っている:

├── audio 
│   └── delete_me.mp3 
├── words 
│   └── audio 
│    └── delete_me.mp3 
│   └── images 
│    └── delete_me.jpg 
└── keep_me.txt 

私はfindKeepers.shという名前のbashスクリプトがあります:私は出力にkeep_me.txtファイルへのパスをそれを期待

#!/usr/bin/env bash 

findKeepers() { 
    local dir=$1 
    echo "$(find $dir -type f ! -name delete_me*)" 
} 

findKeepers /path/to/directory 

を。代わりに、私は空白の行を取得します。私は、コマンドラインから同じコマンドであることを私には思えるが何を実行した場合

  

、私は私が期待するものを手に入れる:代わりに、すべてのファイルの検索がkeep_me

dir=/path/to/directory; echo "$(find $dir -type f ! -name delete_me*)" 
/path/to/directory/keep_me.txt 

と呼ばれていない場合は、 bashスクリプトはオーディオフォルダを無視します。ここfindUnwanted.shと呼ばれる別のbashスクリプトがあります:

#!/usr/bin/env bash 

findUnwanted() { 
    local dir=$1 
    echo "$(find $dir -type f ! -name keep_me*)" 
} 

findUnwanted /path/to/directory 

ここでの結果です:

$ ./findUnwanted.sh 
/path/to/directory/words/audio/delete_me.mp3  
/path/to/directory/words/images/delete_me.jpg 

私はコマンドラインから同じことを実行する場合、私はすべての3つのdelete_meのファイルを取得:

$ dir=/path/to/directory; echo "$(find $dir -type f ! -name keep_me*)" 
/path/to/directory/words/audio/delete_me.mp3  
/path/to/directory/words/images/delete_me.jpg 
/path/to/directory/audio/delete_me.mp3  

をbashスクリプトは、wordsフォルダに深く入ることから始まり、次に隣接するフォルダやファイルを検索するために再び出てこないようです。これを行うには、#!/usr/bin/env bash環境に特別なことがありますか?それとも私は見ていないいくつかの他の違いはありますか?


CODA:私はそれがパイロットエラーであったと推測しています。興味のある人は、私の機能の最終版を以下に示します。

#!/usr/bin/env bash 

# Returns 1 if the given directory contains only placeholder files, or 
# 0 if the directory contains something worth keeping 
checkForDeletion() { 
    local _dir=$1 
    local _temp=$(find "$_dir" -type f ! -regex '.*\(unused.txt\|delete_me.*\)') 

    if [ -z "$_temp" ] 
    then 
    return 1 
    fi 
} 

私はこのようにそれを使用します。

parent=/path/to/parent/ 
for dir in $parent*/ 
do 
    checkForDeletion $dir 
    if [ $? = 1 ] 
    then 
    echo "DELETE? $dir" # rm -rf $dir 
    fi 
done 
+2

あなたのコードはうまく動作します。 – PesaThe

+5

私は再現できませんが、関数を書く正しい方法は、パラメータの拡張とパターン引数を引用し、 'find'の出力をキャプチャしないことです:' findKeepers(){local dir = $ 1; find "$ dir" -type f! -name 'delete_me *'; } ' – chepner

+1

対話型シェルと非対話型シェルでは、' nullglob'の設定が異なる場合があります。これは、グロブが何にもマッチしないときの動作を通知するシェルオプションです(これは '-name'の引数を引用しないので、最初の問題です)。これを確認するには、コマンドラインで 'shopt nullglob'を実行し、それをスクリプトに入れます。 –

答えて

0

私はあなたのことを推測しています '!'パイプ全体が破損しています。私はどこに特殊文字をエスケープし、どこべきではない説明では良いことではないよ

echo "$(find $dir -type f -not -name delete_me*)" 

が、物事は異なる動作をするという事実:あなたの最初のコードスニペットは、次のようになりますので、代わりに「-not」を使用してみてくださいその外部関数を使用すると、エスケープが問題になる可能性があります。

関連する問題