2017-02-07 17 views
0

ファイルが既に存在するか変更されているかをチェックするbashスクリプトがあります。これらのいずれかの場合に該当する場合は、ファイルをある場所から別の場所にコピーします。ファイルが存在しており、変更ないを持っている場合Bash: 'cmp'コマンドの出力を無効にすることができません

DIR="$(cd "$(dirname "${BASH_SOURCE}")/my-dir" && pwd)" 
FILE="file.json" 

copy() { 
    local SAME=$(cmp --silent "${DIR}/${FILE}" "${PWD}/${FILE}") 

    if [ ! -f "${PWD}/${FILE}" ] || [ ! $SAME ]; then 
    cp "${DIR}/${FILE}" "${PWD}/${FILE}" && echo "'$FILE' has been copied." || echo "Copy of '$FILE' has failed."; 
    else 
    echo "'$FILE' already exists and has not changed (not copied)."; 
    fi; 
} 

copy 

しかし、それはまだコピーされます。

echo "$SAME"echo $?エコー終了コード以外のものをエコーし​​ません

だから私の質問です:それは条件に「CMP」コマンドの出力を否定することは可能でしょうか?

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

+0

あなたは '$ SAME'を引用していませんので、本当に空であれば、あなたのテストは実際に' [! ] 'であり、'! 'は空ではない文字列なので* always * trueです。 – chepner

+2

'SAME'は終了コードではなく、' cmp'コマンドの出力です。 – anubhava

+0

@TylerDurdenここで、http://stackoverflow.com/tourページには、Stack Overflowがプロと熱心なプログラマーのための質問と回答のサイトです。 – eakl

答えて

0

パラメータ拡張を引用する必要があります。 $SAMEが空の文字列の場合(そして常に--silentを使用しているため)、テストは[ ! ]になります。 !は空でない文字列なので、テストは成功します。

if [ ! -f "${PWD}/${FILE}" ] || [ ! "$SAME" ]; then 

SAMEに必要cmpの出力が含まれています。

SAME=$(cmp "${DIR}/${FILE}" "${PWD}/${FILE}") 

しかし、cmpの実際の出力を無視し、代わりにその終了ステータスを使用する方が良いでしょう。

if [ ! -f "$PWD/$FILE" ] || ! cmp --silent "${DIR}/${FILE}" "${PWD}/${FILE}"; then 
+0

ありがとうございました。このポストで完全な答えを出す人を提供するための次の質問、この状況で引用された変数と引用されていない変数の違いは何ですか? – eakl

+0

どんな状況でも、引用符で囲まれていないパラメータ拡張は単語分割の対象となり、空でない文字列ごとに1単語が 'IFS'の文字で区切られます。拡張が空の場合、ゼロ語が生成されます。一方、引用符で囲まれた展開は、ちょうど1つの単語を生成する明確な空文字列です。 – chepner

+0

今私にとっては非常に明確です。ありがとうございました – eakl

関連する問題