Вы никогда не должны использовать выходные данные ls
в качестве входных данных для другой программы. Это не работает (для любого определения «работы», включающего понятия надежности или безопасности ), и нет никогда никакой необходимости делать это, потому что оболочка выполняет подстановку (т.е. расширение подстановочных знаков )выполняет работу, которую вы пытаетесь выполнить с помощью mis -с использованием ls
. См. Почему не разборls
(и что делать вместо )? .
Если вы должны сделать что-то подобное, используйте find... -exec {} +
или find... -print0 | xargs -0r...
, а неls
-любой из них действительно будет работать и работать безопасно, независимо от того, какие символы есть в именах файлов.
Ваш цикл for
должен быть записан как:
for file in *; do
...
done
Вам даже не нужен цикл for
, если только вы не собираетесь делать что-то еще с каждым $file
внутри цикла.
Вот несколько альтернативных способов сделать то, что делает ваш цикл for, сохраняя вывод md5sum
в массив с именем hashes
и затем выводя его:
с помощьюprintf
:
$ hashes=( $( md5sum * ) )
$ printf '%s %s\n' "${hashes[@]}" > hashes.txt
$ cat hashes.txt
b026324c6904b2a9cb4b88d6d61c81d1 file.1
26ab0db90d72e28ad0ba1e22ee510510 file.2
6d7fce9fee471194aa8b5b6e47267f03 file.3
Обратите внимание, что в строке формата printf
есть два %s
, разделенных двумя пробелами. Это даст тот же результат, что и сам md5sum
.
Кстати, вы можете увидеть, как записи хранятся в массиве с помощьюtypeset -p
:
$ typeset -p hashes
declare -a hashes=([0]="b026324c6904b2a9cb4b88d6d61c81d1" [1]="file.1"
[2]="26ab0db90d72e28ad0ba1e22ee510510" [3]="file.2"
[4]="6d7fce9fee471194aa8b5b6e47267f03" [5]="file.3")
Оболочка разделила вывод md5sum
на слова (, как определено значением переменной оболочки $IFS
), и поместила каждое «слово» в отдельный элемент массива.
с помощьюtee
:
$ hashes=( $( md5sum * | tee hashes.txt) )
$ cat hashes.txt
b026324c6904b2a9cb4b88d6d61c81d1 file.1
26ab0db90d72e28ad0ba1e22ee510510 file.2
6d7fce9fee471194aa8b5b6e47267f03 file.3
Зная это, ответ-ловушка Лассе Климана может быть записан как:
trap ctrl_c INT
ctrl_c() {
printf '%s %s\n' "${hashes[@]}" > hashes.txt
exit 0
}
Впрочем, здесь даже ловушка не нужна. md5sum
с tee
сделают то, что вы хотите -, т.е.одновременно заполнить $hashes
И файл hashes.txt
.
Или, если вы не хотите использовать массив:
$ for file in *; do
hashes+="$(md5sum "$file" | tee -a hashes.txt)"$'\n'
done
$ echo "$hashes"
b026324c6904b2a9cb4b88d6d61c81d1 file.1
26ab0db90d72e28ad0ba1e22ee510510 file.2
6d7fce9fee471194aa8b5b6e47267f03 file.3
Здесь мы используем опцию tee
's -a
(--append
), потому что мы запускаем md5sum
в цикле и не хотим, чтобы каждая итерация перезаписывала файл hashes.txt
.
Примечание :Это всегда будет иметь дополнительную пустую строку в конце строки $hashes
, увеличивая количество строк на 1. Этого не будет при использовании массива.
Машины, вероятно, аварийно завершают работу с kernel panic
, так что вы ничего не увидите в логах, потому что как только происходит panic
, ядро фактически падает и больше не может ничего записывать в логи. Все, что ядро не синхронизировало с диском до сбоя, будет потеряно.
Вы должны включить ядро core dump
с помощью kdump
, которое будет записывать дамп памяти в файл a на локальном диске после срабатывания panic
. Этот файл можно позже проанализировать после того, как машина запустится с помощью таких инструментов, как crash
.
Вы можете прочитать здесь инструкции о том, как включить дамп ядра ядра. Если это не подходит для вашего дистрибутива, вы, вероятно, можете найти другие статьи, объясняющие, как это сделать. После того, как ваша машина вышла из строя и создала дамп ядра, вам нужно будет использовать crash
для его анализа. Хороший учебник можно найти в dedoimedo . Это не обязательно легко, но это единственный способ найти ключ к разгадке сбоев. В дампе ядра вы также можете прочитать журналы, которые не были синхронизированы с диском до сбоя.