Для SD-карты, которая будет использоваться для дополнительного пространства, я не знаю, можно ли это сделать, но по нескольким причинам я считаю, что это не рекомендуется. Специально, если слот SD поврежден / старый, SD-карта повреждена (поскольку это портативное мультимедийное устройство), и, скорее всего, загрузочная часть не распознает SD в некоторых случаях, поэтому он не будет загружаться оттуда. вы также не можете разделить систему на одну небольшую часть внутреннего жесткого диска, а остальную часть на SD.
Теперь для рекомендаций. Я настоятельно рекомендую начать удаление файлов с жесткого диска 4 ГБ. С 100 МБ вы не сможете установить почти ничего (может быть, Damn Small Linux), но не Ubuntu / Lubuntu /? Buntu. В любом случае обновление не позволяет это сообщение, потому что у вас есть 100 МБ, и ему требуется 1.7 Free. Если вы проверите размеры, вы заметите, что дополнительный размер, который он упоминает, на 100 МБ меньше, чем тот, который ему нужен. Поэтому он говорит, что вам нужно освободить AT LEAST 1,6 ГБ с жесткого диска 4 ГБ, чтобы установить его.
В вашем скрипте есть различные возможные точки отказа. Прежде всего, rm *.old* будет использовать globbing для создания списка всех совпадающих файлов и может иметь дело с именами файлов, содержащими пробельные символы. Однако ваш скрипт присваивает переменную каждому результату glob и делает это без кавычек. Это сломается, если ваши имена файлов содержат пробелы. Например:
$ 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 в вашем скрипте. Вы должны globbing .
Следующая возможная проблема заключается в том, что вы, кажется, ожидаете, что *.old.* соответствует файлам с расширением .old. Это не так. Он соответствует «0 или более символов» (*), затем ., затем «старый», затем другой ., а затем «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
Итак, нет совпадающего foe 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 $oldfile могут быть ошибки, когда ваше имя файла содержит любой символ IFS (пробел, табуляция, новая строка) или любой символ глоба (*, ?, []). [!d0 ]
Если присутствует какой-либо символ из IFS, оболочка будет выполнять разбиение слов и на основе наличия расширений имени шаблонов глобусов при расширении переменной.
Так, например, если имя файла foo bar.old., переменная oldfile будет содержать foo bar.old..
Когда вы это делаете:
rm $oldfile
оболочка сначала разбивает разложение oldfile на пробел на два слова, foo и bar.old.. Таким образом, команда становится:
rm foo bar.old.
, что, очевидно, приведет к неожиданному результату. Кстати, если у вас есть какие-либо операторы globbing (*, ?, []) в расширении, то расширение пути также будет выполнено.
Вам нужно процитировать переменные, чтобы получить желаемый результат:
rm "$oldfile"
Теперь не будет разбито слово или расширение пути, поэтому вы должны получить желаемый результат, то есть желаемый файл будет удален. Если какое-либо имя файла начинается с -, тогда выполните:
rm -- "$oldfile"
Вы можете спросить, почему нам не нужно указывать переменные при использовании внутри [[ , причина в том, что [[ является ключевым словом bash и обрабатывает переменное расширение, внутренне сохраняющее литерал расширения.
Теперь пару точек:
[d12 ] Вы должны перенаправить STDERR (exec 2>errorfile) перед командой rm, иначе [[ -s errorfile ]] тест даст ложные срабатывания. Вы использовали [ -s $errorfile ], вы используете переменное расширение $errorfile, которое было бы присвоено NUL errorfile переменная не определена нигде. Возможно, вы имели в виду только [ -s errorfile ], на основе перенаправления STDERR. Если переменная errorfile определена при использовании [ -s $errorfile ], она снова захлестнет вышеупомянутые случаи IFS и заглохнет, поскольку в отличие от [[, [ f35] не обрабатывается внутри bash. В более поздней части скрипта вы пытаетесь cp уже удаленный файл (опять же без цитирования переменной), это не имеет никакого смысла, вы должны проверить, что патрон и внести необходимые исправления на основе вашей цели.