Этот сценарий оболочки в основном работа других людей. Он прошел несколько итераций, и я немного подправил его, одновременно пытаясь полностью понять, как он работает. Я думаю, что понимаю это сейчас, но у меня нет уверенности, чтобы значительно изменить это самостоятельно и рискую потерять данные, когда я запускаю измененную версию. Поэтому я был бы признателен за советы экспертов по улучшению этого скрипта.
Изменения, которые я ищу:
- сделайте его еще более устойчивым к любым странным именам файлов, если это возможно. В настоящее время он обрабатывает пробелы в именах файлов, но не переводит строки. Я могу жить с этим (потому что я пытаюсь найти любые имена файлов с символами новой строки и избавиться от них).
- сделать его более осмысленным в отношении того, какой файл сохраняется в качестве фактического содержимого inode, а какие файлы становятся ссылками sym. Я хотел бы иметь возможность сохранить файл, который является либо: а) кратчайшим путем, б) самым длинным путем, либо в) имеет имя файла с наибольшим количеством буквенных символов (которое, вероятно, будет наиболее описательным именем).
- разрешите ему читать каталоги для обработки либо из параметров, переданных в файл, либо из файла.
- При желании, запишите длинный список всех изменений и / или всех файлов, которые не были обработаны.
Из всех них, № 2 является наиболее важным для меня сейчас. Мне нужно обработать некоторые файлы с ним, и мне нужно улучшить способ выбора файлов для преобразования в символические ссылки. (Я попытался использовать такие вещи, как опция поиска -depth без успеха.)
Вот текущий скрипт:
#!/bin/bash
# clean up known problematic files first.
## find /home -type f -wholename '*Icon*
## *' -exec rm '{}' \;
# Configure script environment
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
set -o nounset
dir='/SOME/PATH/HERE/'
# For each path which has multiple links
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# (except ones containing newline)
last_inode=
while IFS= read -r path_info
do
#echo "DEBUG: path_info: '$path_info'"
inode=${path_info%%:*}
path=${path_info#*:}
if [[ $last_inode != $inode ]]; then
last_inode=$inode
path_to_keep=$path
else
printf "ln -s\t'$path_to_keep'\t'$path'\n"
rm "$path"
ln -s "$path_to_keep" "$path"
fi
done < <( find "$dir" -type f -links +1 ! -wholename '*
*' -printf '%i:%p\n' | sort --field-separator=: )
# Warn about any excluded files
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
buf=$( find "$dir" -type f -links +1 -path '*
*' )
if [[ $buf != '' ]]; then
echo 'Some files not processed because their paths contained newline(s):'$'\n'"$buf"
fi
exit 0