Почему моя инструкция if с backticks не работает должным образом?
Я пытаюсь создать Bash script, где пользователь сможет скопировать файл и посмотреть, успешно ли он был выполнен или нет. Но каждый раз, когда копия выполняется, правильно или нет, отображается вторая выходная "копия не была". Любая идея, как это решить?
if [ `cp -i $files $destination` ];then
echo "Copy successful."
else
echo "Copy was not done"
fi
Ответы
Ответ 1
Вы хотите
if cp -i "$file" "$destination"; then #...
Не забывайте кавычки.
Ваша версия:
if [ `cp -i $files $destination` ];then #..
всегда будет выполнять ветвь else
.
Оператор if в командной оболочке принимает команду.
Если эта команда завершается успешно (возвращает 0
, которая назначается в $?
), то условие выполняется успешно.
Если вы делаете if [ ... ]; then
, то это то же самое, что и
if test ... ; then
потому что [ ]
является синтаксическим сахаром для test command/builtin.
В вашем случае вы передаете результат stdout * операции cp
в качестве аргумента test
Операция stdout cp
будет пуста (cp
обычно выводит только ошибки, а те идут в stderr). A test
вызов с пустым списком аргументов является ошибкой. Ошибка приводит к ненулевому статусу выхода, и поэтому вы всегда получаете ветвь else
.
* подстановка процесса $()
или замена подпрограммы обратного потока slurp stdout команды, которую они запускают
Ответ 2
С обратными тиками вы проверяете вывод команды cp, а не ее статус. Здесь вам также не нужна команда тестирования (квадратные скобки).
Просто используйте:
if cp ... ; then
...
Ответ 3
В дополнение к проверке состояния выходных стилей, как указано в другом ответе, вы можете использовать составную команду для выполнения именно того, что вы пытаетесь, без полного синтаксиса 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'
Примечание. обязательно указывайте свои переменные, чтобы предотвратить расщепление слов, расширение пути и т.д.
Ответ 4
Try:
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