# Get one character per loop, until the user presses <Enter>
while true ; do
read -n 1 c
(( ${#c} == 0 )) && break # Exit the loop. Input length is 0
# ie. The user has pressed Enter
#
if [ \( ! "$c" \< "a" -a ! "$c" \> "z" \) \
-o \( ! "$c" \< "A" -a ! "$c" \> "Z" \) ]
then
val=($(ascii -s $c)) # build an array of ascii info for this char
echo " ... The decimal value of $c is: ${val[1]}"
else
echo -n $'\r \r' # overwrite the invalid character
fi
done
sha1sum
выводы будут уникальны, пока исходные данные уникальны. (Если Вы не очень чрезвычайно неудачны, и Вы нашли некоторых sha1sum
коллизия).
Что касается Вашего варианта использования: это - хорошая привычка использовать printf '%s' "$fname"
вместо echo "$fname"
, первый будет работать когда $fname
-n
, или -e
, … Видят также enzotib комментарий, я пропустил это на первый взгляд.
Кроме того, я не уверен точно, что является Вашими мотивациями, но можно рассмотреть питание sha1sum
с содержанием файла вместо имен файлов. Таким образом, Вы получили бы уникальное имя файла для каждого уникального содержания.
Во-первых, несколько вопросов оболочки:
for fname in `find …`
поскольку это исказит имена файлов и перестанет работать (потому что командная строка является слишком длинной), если существует слишком много файлов со слишком длинными именами. Использовать find -exec
вместо этого. Так как Вы должны окружить расширение в команде, выполняемой find
, вызовите оболочку."$fname"
, "$(echo …)"
).echo
обратные косые черты искажений на нескольких оболочках (это также искажает несколько начала аргументов -
, но это не проблема здесь, так как все аргументы начнутся ./
). Способ распечатать любую строку буквально printf "%s\n" "$fname"
, или printf "%s"
"$fname" для предотвращения заключительной новой строки. Здесь я не вижу оснований для взятия хеша имени файла плюс заключительная новая строка в противоположность хешу имени файла.Таким образом, мы получаем эту команду:
find . -type f -exec sh -c 'mv "$0" "$(printf "%s" "$0" | sha1sum | cut -f1 -d" ").html' {} \;
Это будет немного быстрее для вызова оболочки для целого пакета имен сразу.
find . -type f -exec sh -c 'for fname; do mv "$fname" "$(printf "%s" "$fname" | sha1sum | cut -f1 -d" ").html; done' _ {} +
Проблема с этим методом - это если mv
начинает действовать прежде find
закончил пересекать каталог, файлы, которые были перемещены, могут быть взяты mv
. Это не проблема с Вашей командой, потому что она ожидает find
закончиться прежде, чем запустить движущиеся файлы. Так помещает переименованные файлы в другую иерархию каталогов. Это решит другую проблему, которую также имеет Ваша предложенная команда, который является этим mv
может перезаписать существующий файл, который, оказывается, называют <sha1sum>.html
.
mkdir ../staging
find . -type f -exec sh -c 'for fname; do mv "$fname" ../staging/"$(printf "%s" "$fname" | sha1sum | cut -f1 -d" ").html; done' _ {} +
find . -depth \! -name "." -type d -exec rmdir {} +
mv ../staging/* .
Теперь по Вашему основному вопросу: два файла с различными путями отобразятся на два различных хеша SHA-1. Математически разговор, там существуйте отличные строки с идентичными хешами SHA-1 (это очевидно, так как существует бесконечно много строк, но только конечно много хешей). Однако в сущности никто не знает, как найти их: нет никакой известной коллизии для SHA-1. Возможно, что однажды в будущем SHA-1 будет поврежден, в этом случае Ваша процедура будет безопасна только против случайных коллизий, не против злонамеренных взломщиков. Если это происходит (не скоро), необходимо обновить до того, что считают безопасным хеш-алгоритмом в то время.
Что касается Вашего второго вопроса: хеш полностью определяется строкой, которую Вы хешируете. Таким образом, если у Вас есть два названные файла tweedledum/staple
и tweedledee/staple
и Вы выполняете ту процедуру переименования из каждого каталога tweedledee
и tweedledum
в свою очередь затем оба каталога закончатся с названным файлом 1c0ee9c1eed005a476403c7651b739ae5bc7cf2a.html
. Если Вы хотите иметь различные имена, необходимо поместить некоторое различающее содержание в хешированный текст, такой как название каталога.
В первую очередь, я предлагаю занять место
for fname in `find . -type f`; do
с
find . -type f | while read -r fname; do
Затем, относительно sha1sum, это должно быть "фактически" уникально, означая, что вероятность, чтобы иметь в различные файлы с той же контрольной суммой, если значительно низкий, так, чтобы можно было безопасно принять это, уникальна.