ArrayIndexOutOfBoundsException
означает, что вы пытаетесь получить доступ к индексу массива, который не существует или не связан с границей этого массива. Индексы массива начинаются с 0 и заканчиваются на длину - 1.
В вашем случае
for(int i = 0; i<=name.length; i++) {
System.out.print(name[i] +'\n'); // i goes from 0 to length, Not correct
}
ArrayIndexOutOfBoundsException
происходит, когда вы пытаетесь получить доступ к элементу index.length, который делает не существует (индекс массива заканчивается на -1). просто заменяя & lt; = с & lt; решит эту проблему.
for(int i = 0; i < name.length; i++) {
System.out.print(name[i] +'\n'); // i goes from 0 to length - 1, Correct
}
Что я сделал неправильно в сценарии?
blockquote>Ваш сценарий пытается сжать каждый файл, но команда
gzip
отклоняет файлы, уже заархивированные[ 114] Как я могу предотвратить эту ошибку?blockquote>
Попросите скрипт проверить, является ли файл сжатым или нет, и только gzip, если он соответствует (1). Кроме того, вы можете принудительно выполнить повторное сжатие, даже если оно уже сжато (2).
Переходя к варианту № 1):
getBackup () { if [[ ! -e $pid ]] then if [[ $usage -le $space ]] then touch $pid find $backupDirectory -mtime +15 -type f -delete; for i in $(find $logsDirectory -type f -not -path "*/irws/*") do /sbin/fuser $i > /dev/null 2>&1 if [ $? -ne 0 ] then if [[ $i =~ \.gz$ ]] # File is already zipped mv -v $i $backupDirectory else gzip $i mv -v $i.gz $backupDirectory fi else continue fi done [[ ! -z $email ]] && echo "Backup is ready" | mas"Backup" $email rm -f $pid fi fi }
Ваш скрипт содержит ряд неуклюжих или неэффективных антипаттернов. Вот рефакторинг. Единственное реальное изменение - это пропуск любых *.gz
файлов.
#!/bin/bash
logsDirectory="/test//logs/"
email=""
backupDirectory="/test/backup"
pid="/data/test/scripts/backup.pid"
# Avoid useless use of grep -- awk knows how to match a regex
# Better still run df /data/logs
usage=$(df /data/logs/ | awk '{ print $2 }')
space=450000000
getBackup ()
{
# Quote variables
if [[ ! -e "$pid" ]]; then
if [[ "$usage" -le "$space" ]]; then
touch "$pid"
find "$backupDirectory" -mtime +15 -type f -delete;
# Exclude *.gz files
# This is still not robust against file names with spaces or wildcards in their names
for i in $(find "$logsDirectory" -type f -not -path "*/irws/*" -not -name '*.gz')
do
# Avoid useless use of $?
if /sbin/fuser "$i" > /dev/null 2>&1
then
gzip "$i"
mv -v "$i.gz" "$backupDirectory"
# no need for do-nothing else
fi
done
[[ ! -z "$email" ]] &&
echo "Backup is ready" | mas"Backup" "$email"
rm -f "$pid"
fi
fi
}
getBackup
С немного более навязчивым рефакторингом правильное исправление цикла find
, возможно, будет выглядеть примерно как
find "$logsDirectory" -type f \
-not -path "*/irws/*" -not -name '*.gz' \
-exec sh -c '
for i; do
if /sbin/fuser "$i" > /dev/null 2>&1
then
gzip "$i"
mv -v "$i.gz" "$backupDirectory"
fi
done' _ {} +
, где секретный соус должен передать find ... -exec +
в аргументах к сценарию sh -c
таким образом, чтобы вообще не включать в себя аргументы текущей оболочки.