2017-02-07 3 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 $? эху код выхода не эхо

Так что мой вопрос: можно отрицать вывод команды «КСС» в состоянии?

Спасибо.

+0

Вы не цитируете '$ SAME', поэтому, если он действительно пуст, ваш тест на самом деле' [! ] ', который всегда равен * 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

Как и в любой ситуации, расширение без кавычек может быть разбито на слово, что приводит к одному слову на непустую строку, разделенную символами в 'IFS'. Если расширение пустое, то генерируются нулевые слова. С другой стороны, цитированное расширение представляет собой определенную, хотя и возможно пустую строку, которая вырабатывает ровно одно слово. – chepner

+0

Теперь это очень ясно. спасибо – eakl