Почему мой оператор 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