Почему мой оператор if с обратными галочками не работает должным образом?

Я пытаюсь создать сценарий Bash, где пользователь сможет скопировать файл и посмотреть, был ли он успешно выполнен или нет. Но каждый раз, когда копирование выполняется, правильно или нет, отображается второй вывод "копия не была выполнена". Есть идеи, как это решить?

if [ `cp -i $files $destination` ];then
        echo "Copy successful."
else
        echo "Copy was not done"
fi

4 ответа

Решение

Что вы хотите

if cp -i "$file" "$destination"; then #...

Не забывайте цитаты.


Ваша версия:

if [ `cp -i $files $destination` ];then #..

всегда выполнит else ветка.

Оператор if в оболочке принимает команду. Если эта команда выполнена успешно (возвращает 0, который назначается в $?), то условие выполняется успешно.

Если вы делаете if [ ... ]; then тогда это так же, как if test ... ; then так как [ ] является синтаксическим сахаром для команды test /builtin.

В вашем случае вы передаете результат стандартного вывода * cp операция в качестве аргумента test

Выход из cp операция будет пустой (cp как правило, только выводит ошибки и те идут в stderr). test вызов с пустым списком аргументов является ошибкой. Ошибка приводит к ненулевому состоянию выхода и, таким образом, вы всегда получаете else ветка.


* $() подстановка процесса или обратный процесс подстановки подрывают стандартный вывод команды, которую они запускают

С обратными галочками вы проверяете вывод команды cp, а не ее статус. Вам также не нужна команда теста (квадратные скобки) здесь.

Просто используйте:

if cp ... ; then
    ...

В дополнение к проверке состояния выходных стихов, как правильно указано в другом ответе, вы можете использовать составную команду, чтобы сделать именно то, что вы пытаетесь, не требуя полного if ... then ... else ... fi синтаксис. Например:

cp -i "$files" "$destination" && echo "Copy successful." || echo "Copy was not done"

Который по существу делает то же самое, что и if синтаксис. В принципе:

command && 'next cmd if 1st succeeded'

а также

command || 'next cmd if 1st failed'

Вы просто используете command && 'next cmd if 1st succeeded' как command в command || 'next cmd if 1st failed', Вместе это просто:

command && 'next cmd if 1st succeeded' || 'next cmd if 1st failed'

Примечание: убедитесь, что вы всегда заключаете в кавычки ваши переменные, чтобы предотвратить расщепление слов, расширение пути и т. Д.

Пытаться:

                cp -i $files $destination
                #check return value $? if cp command was successful
                if [ "$?" == "0" ];then
                        echo "Copy successful."

                else
                        echo "Copy was not done"
                fi
Другие вопросы по тегам