Ошибки указывают на аппаратную проблему с диском, но только в секторах, содержащих данные.
Причина, по которой в Windows вы не видите этих ошибок (до сих пор), вероятно, связана с различием в программном обеспечении для просмотра файлов: большинство файловых браузеров Linux считывают больше информации о файлах, из файла при открытии папки, чем Проводник Windows. Это делается для того, чтобы сделать предварительный просмотр и получить метаданные для файлов. Windows, вероятно, получает это только по явному запросу.
Вы можете попробовать и посмотреть, сможете ли вы скопировать все файлы под Windows на отдельный диск. Если это сработает, запустите тщательный анализатор диска на исходном диске, прежде чем продолжить его использование (после создания полной резервной копии).
Eliminar letras de cadenas es fácil de hacer de una sola vez sin iterar sobre los caracteres de la cadena. Esto podría hacerse con tr
así:
#!/bin/sh
perms="$( printf '%s' "$1" | tr -c -d 'rwx' )"
chmod u+"$perms" "$2"
Esto usa tr
para eliminar primero todo del argumento de la primera línea de comando que no sea ninguno de los caracteres r
, w
o x
, luego ejecuta chmod
.
Tenga en cuenta la cita de las expansiones, especialmente "$2"
. Sin estas comillas, no podría usar su secuencia de comandos en archivos con espacios o caracteres de nombre de archivo en sus nombres (, consulte p. " ¿Por qué mi script de shell se ahoga con espacios en blanco u otros caracteres especiales? " ).
En bash
, puede usar una sustitución de parámetro como
perms=${1//[!rwx]/}
Esto elimina todo lo que no es r
, w
o x
de $1
y asigna el resultado a perms
.
El guión bash
se convierte en
#!/bin/bash
chmod u+"${1//[!rwx]/}" "$2"
Usando
shift
chmod u+"$perms" "$@"
donde $perms
se calcula de cualquiera de las formas anteriores(antes de el shift
), incluso podría hacer que su secuencia de comandos realice el cambio en varios archivos a la vez. El shift
elimina el primer argumento de la línea de comando de la lista y "$@"
se expandirá al resto de los argumentos,cada uno citado individualmente.
Si necesita absolutamente iterar sobre los caracteres de la cadena (no ), entonces puede hacerlo así:
#!/bin/bash
string="$1"
for (( i = 0; i < ${#string}; ++i )); do
ch="${string:i:1}"
if [[ "$ch" == [rwx] ]] && [[ "$new_string" != *$ch* ]]; then
new_string+=$ch
fi
done
printf 'The new string is "%s"\n' "$new_string"
Esto construye una nueva cadena a partir de la anterior agregando r
, w
o x
si el carácter actual en la cadena original es uno de esos caracteres, y si el el carácter aún no existe en la nueva cadena (no es necesario para la operación dechmod
).
En lugar de usar seq
, usamos un bucle for
que va de cero a uno menos que la longitud de la cadena original, y para facilitar la lectura y no repetirnos, extraemos el carácter actual en ch
en cada iteración.
En lugar de tres pruebas en el carácter, realizamos una sola coincidencia de patrón para ver si es r
, w
o x
.
${permisos/perm_actual/}
elimina la cadena literal perm_actual
del valor de la variable, creo que quiere ${permisos/$perm_actual/}
en su lugar.
Pero podría usar permisos=${permisos//[^rwx]}
en lugar del bucle para eliminar todos los caracteres que no sean-rwx
de una sola vez, y [[ $permisos = *[^rwx]* ]]
para verificar si la variable tiene alguno de ellos.
(Tanto ${foo//bar}
como [[.. ]]
son extensiones no estándar, pero ya las usó, por lo que probablemente esté ejecutando Bash/ksh/zsh.)