Arrays BASH问题,为循环计算数组中的变量
我对下面的脚本有问题。由于我对BASH缺乏了解,所以我无法100%确定如何创建一个循环,该循环使用“for”来计算数组中的变量数量,并通过每个变量进行循环。基本上,我想要做的是让脚本计算变量$sqldumps中的变量数量,然后为每个变量运行一个MySQL转储(同时将它们记录到数据库中)。脚本的长版本发布在底部,但下面是一个短版本:Arrays BASH问题,为循环计算数组中的变量,arrays,bash,variables,for-loop,count,Arrays,Bash,Variables,For Loop,Count,我对下面的脚本有问题。由于我对BASH缺乏了解,所以我无法100%确定如何创建一个循环,该循环使用“for”来计算数组中的变量数量,并通过每个变量进行循环。基本上,我想要做的是让脚本计算变量$sqldumps中的变量数量,然后为每个变量运行一个MySQL转储(同时将它们记录到数据库中)。脚本的长版本发布在底部,但下面是一个短版本: #! /usr/bin/env bash echo -ne '\033]0;World of Clucky - Backup\007' BINDIR="$(dirna
#! /usr/bin/env bash
echo -ne '\033]0;World of Clucky - Backup\007'
BINDIR="$(dirname "$(readlink -fn "$0")")"
cd "$BINDIR"
sqldumps=("lwc" "bans" "frisnuk_permissions" "jail" "imonies" "GriefP" "permissions" "showcase" "simpleclans")
#Copy MySQL Databases
echo "[`date '+%H:%M'`] Starting MySQL Backup" >> /home/clucky/MinecraftServers/backup.log
for i in ${#sqldumps[*]}
do
echo " ${sqldumps[i]}" >> /home/clucky/MinecraftServers/backup.log;
/opt/lampp/bin/mysqldump -u'root' -p'CENSORED' --skip-lock-tables ${sqldumps[i]} > /home/clucky/MinecraftServers/.backups/$timedate/MySQL/${sqldumps[i]}.sql;
done
echo " forum";
/opt/lampp/bin/mysqldump -u'root' -p'CENSORED' forum >> /home/clucky/MinecraftServers/.backups/$timedate/MySQL/forum.sql;
echo "[`date '+%H:%M'`] MySQL Backup Complete" >> /home/clucky/MinecraftServers/backup.log
我遇到的问题是:
for i in ${#sqldumps[*]}
我假设我使用了错误的语法,所以如果有人能给我正确的,我将不胜感激。谢谢大家!
#! /usr/bin/env bash
echo -ne '\033]0;World of Clucky - Backup\007'
BINDIR="$(dirname "$(readlink -fn "$0")")"
cd "$BINDIR"
timedate=`date '+%m.%d.%Y-%H:%M'`
sqldumps=("lwc" "bans" "frisnuk_permissions" "jail" "imonies" "GriefP" "permissions" "showcase" "simpleclans")
echo "-------------- `date '+%d-%B-%Y %H:%M'` --------------" >> /home/clucky/MinecraftServers/backup.log
echo "[`date '+%H:%M'`] Starting Minecraft Backup" >> /home/clucky/MinecraftServers/backup.log
mkdir -p /home/clucky/MinecraftServers/.backups/$timedate
mkdir -p /home/clucky/MinecraftServers/.backups/$timedate/MySQL
nice --adjustment=19 tar -zcpf /home/clucky/MinecraftServers/.backups/$timedate/Minecraft.tar.gz \
--directory /home/clucky/MinecraftServers/ \
--exclude=SkyBlockkit \
--exclude=Tekkit \
--exclude=Vanilla \
--exclude=test \
--exclude=Zflocco_LP \
--exclude=Mortuus/plugins/dynmap/web --exclude=Mortuus/plugins/AutoSaveWorld/backups --exclude Mortuus/CraftBukkitVersion --exclude=Mortuus/orebfuscator_cache --exclude=Mortuus/plugins/#Removed --exclude=Mortuus/server.log \
--exclude=Frisnuk/plugins/dynmap/web --exclude=Frisnuk/plugins/AutoSaveWorld/backups --exclude Frisnuk/CraftBukkitVersion --exclude=Frisnuk/orebfuscator_cache --exclude=Frisnuk/plugins/#Removed --exclude=Frisnuk/plugins/#AwaitingUpdate --exclude=Frisnuk/server.log --exclude=Frisnuk/Suwako_Moriya100 --exclude=Frisnuk/Uk_Shadow --exclude=Frisnuk/Whiteghost99 --exclude=Frisnuk/greenrangermatt \
--exclude=dailybackup.log \
--exclude=.backups \
--exclude=backup.log \
--exclude=backups.log \
--exclude=backupscript.sh \
--exclude=dailybackup.sh \
--exclude=.keptbackups .
echo "[`date '+%H:%M'`] Minecraft Backup Complete" >> /home/clucky/MinecraftServers/backup.log
#Purge files 3 days old
echo "[`date '+%H:%M'`] Purging Old Backups" >> /home/clucky/MinecraftServers/backup.log
find /home/clucky/MinecraftServers/.backups* -mmin +4320 -exec rm --recursive {} \;
echo "[`date '+%H:%M'`] Purging Complete" >> /home/clucky/MinecraftServers/backup.log
#Copy MySQL Databases
echo "[`date '+%H:%M'`] Starting MySQL Backup" >> /home/clucky/MinecraftServers/backup.log
for i in ${#sqldumps[*]}
do
echo " ${sqldumps[i]}" >> /home/clucky/MinecraftServers/backup.log;
/opt/lampp/bin/mysqldump -u'root' -p'CENSORED' --skip-lock-tables ${sqldumps[i]} > /home/clucky/MinecraftServers/.backups/$timedate/MySQL/${sqldumps[i]}.sql;
done
echo " forum";
/opt/lampp/bin/mysqldump -u'root' -p'CENSORED' forum >> /home/clucky/MinecraftServers/.backups/$timedate/MySQL/forum.sql;
echo "[`date '+%H:%M'`] MySQL Backup Complete" >> /home/clucky/MinecraftServers/backup.log
echo "[`date '+%H:%M'`] Daily Backup Complete" >> /home/clucky/MinecraftServers/backup.log
#Read back file size
filesize=$(ls -lah /home/clucky/MinecraftServers/.backups/$timedate | awk '{ print $5}')
echo " Total Compression Size: $filesize\n" >> /home/clucky/MinecraftServers/backup.log
谢谢你的帮助 不要在数组上建立索引,只需使用以下值:
for value in "${sqldumps[@]}"; do echo $value; done
不要在数组上建立索引,只需使用以下值:
for value in "${sqldumps[@]}"; do echo $value; done
语法${#varname[*]}
返回数组的大小,但是您使用的语法希望得到元素列表。所以,要么你想要:
for elem in "${varname[@]}"; do
... something with ${elem} ...
done
或
for((i=0;i<${varname[@]};i++);做
... 带有${varname[$i]}的内容。。。
完成
注意,我使用@
而不是*
,因为这通常是对包含空格的元素的一种很好的预防措施(即使在这种情况下可能不是严格必要的)。语法${varname[*]}
返回数组的大小,但是您使用的语法希望得到一个元素列表。所以,要么你想要:
for elem in "${varname[@]}"; do
... something with ${elem} ...
done
或
for((i=0;i<${varname[@]};i++);做
... 带有${varname[$i]}的内容。。。
完成
注意,我使用了@
而不是*
,因为这通常是一种很好的预防措施,可以防止包含空格的元素(即使在这种情况下可能不是严格必要的)。我已经冒昧地重新组织了脚本,使其更具可读性
#!/usr/bin/env bash
# Script starts here.
main() {
backup_dir=~clucky/MinecraftServers
dbs=(lwc bans frisnuk_permissions jail imonies GriefP permissions showcase simpleclans forum)
echo -ne '\033]0;World of Clucky - Backup\007'
log 'Starting MySQL Backup'
dump_dbs "${dbs[@]}"
log 'MySQL Backup Complete'
}
# Write a timestamped message to the log file.
log() {
echo "[$(date '+%H:%M')] $*" >> "$backup_dir/backup.log"
}
# Dump each of the databases passed as an argument. The list of databases is "$@".
dump_dbs() {
for db in "$@"; do
# Use --skip-lock-tables for every database except "forum".
local options=(--skip-lock-tables)
[[ $db = forum ]] && options=()
log " $db"
/opt/lampp/bin/mysqldump -u root -p CENSORED "${options[@]}" "$db" \
> "$backup_dir/.backups/$timedate/MySQL/$db.sql"
done
}
main "$@"
以下是我做的一些事情:
这样的循环将直接迭代每个值,而不是迭代数组索引:
for value in "${array[@]}"; do ...; done
使用~user
引用用户的主目录要短一些。它也更安全,因为用户的主目录不一定在/home
下
将代码分解为单独的函数有助于消除一些冗余,例如重复将完整路径写入backup.log
。函数的作用是:将带时间戳的消息行放在一个位置
论坛
表没有得到--skip lock tables
选项,因此我更明确地说明了这一点,从而可以消除重复的mysqldump
行
我删除了不需要的地方的引用
我冒昧地重新组织了一下您的脚本,使其更具可读性
#!/usr/bin/env bash
# Script starts here.
main() {
backup_dir=~clucky/MinecraftServers
dbs=(lwc bans frisnuk_permissions jail imonies GriefP permissions showcase simpleclans forum)
echo -ne '\033]0;World of Clucky - Backup\007'
log 'Starting MySQL Backup'
dump_dbs "${dbs[@]}"
log 'MySQL Backup Complete'
}
# Write a timestamped message to the log file.
log() {
echo "[$(date '+%H:%M')] $*" >> "$backup_dir/backup.log"
}
# Dump each of the databases passed as an argument. The list of databases is "$@".
dump_dbs() {
for db in "$@"; do
# Use --skip-lock-tables for every database except "forum".
local options=(--skip-lock-tables)
[[ $db = forum ]] && options=()
log " $db"
/opt/lampp/bin/mysqldump -u root -p CENSORED "${options[@]}" "$db" \
> "$backup_dir/.backups/$timedate/MySQL/$db.sql"
done
}
main "$@"
以下是我做的一些事情:
这样的循环将直接迭代每个值,而不是迭代数组索引:
for value in "${array[@]}"; do ...; done
使用~user
引用用户的主目录要短一些。它也更安全,因为用户的主目录不一定在/home
下
将代码分解为单独的函数有助于消除一些冗余,例如重复将完整路径写入backup.log
。函数的作用是:将带时间戳的消息行放在一个位置
论坛
表没有得到--skip lock tables
选项,因此我更明确地说明了这一点,从而可以消除重复的mysqldump
行
我删除了不需要的地方的引用
$i
将保存数组中的每个项,直到它到达末尾。因此,您不必每次在for
循环中需要数组时都引用它。我也不喜欢硬编码echo
,这是我个人的喜好,所以我用printf
替换了它
for i in ${#sqldumps[@]}
do
printf " %s" "$i" >> /home/clucky/MinecraftServers/backup.log;
/opt/lampp/bin/mysqldump -u'root' -p'CENSORED' --skip-lock-tables $i > /home/clucky/MinecraftServers/.backups/$timedate/MySQL/${sqldumps[i]}.sql;
done
如果您只想找到可以使用的数组的大小
Length=${#sqldumps[@]}
然后,$Length
将等于数组中的位数$i
将保存数组中的每个项,并不断递增,直到其到达末尾。因此,您不必每次在for
循环中需要数组时都引用它。我也不喜欢硬编码echo
,这是我个人的喜好,所以我用printf
替换了它
for i in ${#sqldumps[@]}
do
printf " %s" "$i" >> /home/clucky/MinecraftServers/backup.log;
/opt/lampp/bin/mysqldump -u'root' -p'CENSORED' --skip-lock-tables $i > /home/clucky/MinecraftServers/.backups/$timedate/MySQL/${sqldumps[i]}.sql;
done
如果您只想找到可以使用的数组的大小
Length=${#sqldumps[@]}
然后,$Length
将等于数组中的位数您需要知道数组中变量的数量,还是可以使用数组“映射”方法?事实上,我真的不知道。我只需要一种方法让脚本循环遍历数组$sqldumps中的所有变量,并为每个变量运行一个MySQL转储。你需要知道数组中变量的数量,还是可以使用数组“map”方法?事实上,我真的不知道。我只需要让脚本循环遍历数组$sqldumps中的所有变量,并为每个变量运行一个MySQL转储。我确实需要变量I
每次递增1,对吗?那么我该如何指定呢?@JesseAaronBellas:使用此表单,您根本不需要I
。您唯一需要它的是获取数组中的i
第四个元素,这个表单直接提供这些元素。只要在循环中用$value
替换${sqldumps[i]}
,就可以设置了。我确实需要变量i
每次递增1,对吗?那么我该如何指定呢?@JesseAaronBellas:使用此表单,您根本不需要I
。您唯一需要它的是获取数组中的i
第四个元素,这个表单直接提供这些元素。只是