В вашем скрипте есть различные возможные точки отказа. Прежде всего, rm *.old*
будем использовать глобирование для создания списка всех подходящих файлов, которые могут иметь дело с именами файлов, содержащими пробелы. Однако ваш сценарий назначает переменную каждому результату глобуса и делает это без кавычек. Это сломается, если ваши имена файлов содержат пробелы. Например:
$ ls
'file name with spaces.old.txt' file.old.txt
$ rm *.old.* ## works: both files are deleted
$ touch "file.old.txt" "file name with spaces.old.txt"
$ for i in ./*; do oldfile=$i; rm -v $oldfile; done
rm: cannot remove './file': No such file or directory
rm: cannot remove 'name': No such file or directory
rm: cannot remove 'with': No such file or directory
rm: cannot remove 'spaces.old.txt': No such file or directory
removed './file.old.txt'
Как видите, цикл не удался для файла с пробелами в его имени. Чтобы сделать это правильно, вам нужно заключить переменную в кавычки:
$ for i in ./*; do oldfile="$i"; rm -v "$oldfile"; done
removed './file name with spaces.old.txt'
removed './file.old.txt'
Та же проблема касается почти каждого использования $i
в вашем скрипте. Вы должны всегда указывать свои переменные .
Следующая возможная проблема заключается в том, что вы, похоже, ожидаете, что *.old.*
файлы совпадут с расширением .old
. Это не так. Он соответствует «0 или более символов» ( *
), затем a .
, затем «old», затем другому, .
а затем «0 или более символов снова». Это означает, что он не будет совпадать с чем-то вроде file.old
, а только с чем-то вроде `file.old.foo:
$ ls
file.old file.old.foo
$ for i in *; do if [[ "$i" == *.old.* ]]; then echo $i; fi; done
file.old.foo
Таким образом, противник не совпадает file.old
. В любом случае ваш сценарий намного сложнее, чем нужно. Попробуйте это вместо этого:
#!/bin/bash
for i in *; do
if [[ -f "$i" ]]; then
if [[ "$i" == *.old ]]; then
rm -v "$i" || echo "rm failed for $i"
else
echo "$i doesn't have an .old extension"
fi
cp -v "$i" "$i".old
else
echo "$i is not a file"
fi
done
Обратите внимание, что я добавил -v
к операторам rm
и cp which does the same thing as what you were doing with your
echo`.
Это не идеально, поскольку, когда вы найдете, например, file.old
что это будет удалено, а позже скрипт попытается скопировать его и потерпит неудачу, так как файл больше не существует. Тем не менее, вы не объяснили, что на самом деле пытается сделать ваш сценарий, поэтому я не могу исправить это для вас, если вы не скажете нам, что вы действительно пытаетесь выполнить.
Если вы хотите: i) удалить все файлы с .old
расширением и ii) добавить .old
расширение к любым существующим файлам, у которых его нет, все, что вам действительно нужно, это:
#!/bin/bash
for i in *.old; do
if [[ -f "$i" ]]; then
rm -v "$i" || echo "rm failed for $i"
else
echo "$i is not a file"
fi
done
## All the ,old files have been removed at this point
## copy the rest
for i in *; do
if [[ -f "$i" ]]; then
## the -v makes cp report copied files
cp -v "$i" "$i".old
fi
done
rm *.old.*
удаляются эти файлы. но не файл резервной копии file.old. Я пытаюсь сделать это в моем сценарии. Спасибо