-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
关于while read line 循环中变量作用域的问题 #93
Comments
前一阵用shell写了一个从数据库中抽取数据生成.xml文件的脚本,要求是每个文件中只生成1000条数据。于是用到了while read line 作为循环。 在制作文件计数器的时候发现了一个问题,在执行的过程中文件计数器(FILENUM)总是出现返回初始值的现象,具体简化的脚本如下: #/bin/bash
FILENUM=1
for i in (多个表)
do
#sql 语句 > .swap
COUNTER=0
cat .swap | while read line
do
#变量赋值以及写入文件的内容(不是重点,没细写)
COUNTER=$[COUNTER+1]
if [ $COUNTER -eq 1000 ]
then
#封包操作,封包的包名中附带了$FILENAME(没细写)
FILENUM=$[FILENUM+1]
fi
done
#封包操作,封包的包名中附带了$FILENAME,因为不能保证是1000条整数,所以read line跳出后还是需要执行这个操作。
FILENUM=$[FILENUM+1]
done 基本流程如上: 在执行过程中发现文件计数器FILENUM总是有还原成默认值的情况。 经过调试发现,每一次while read line 循环的文件完成之后都会发生这种现象。 启动sh的时候同时也发现了两个同名的*.sh进程 经过查阅资料,发现在while read line 的用法中常用的有两种。
经过分别测试得出以下结论: 使用管道符 | 的方法相当于启动了一个独立的子进程,因此循环中的变量FILENUM是属于自进程中的,与循环外的FILENUM虽然同名,但是值却不同。 使用重定向 < 的方法则不会有这种现象,在脚本启动时并没有子进程出现,因此循环内部变量FILENUM与循环外的FILENUM变量在同一个bash shell中。 |
#!/bin/bash
tmpfile=/root/multipath_tmp
[ -e "$tmpfile" ] && rm -rf $tmpfile
this_inode=$(ifconfig Mgnt-0 | grep "inet " | awk '{print $2}')
function explain_one_foreach () {
for lun in $(cat "$WWIDS" | grep -v ^# | sed s#/##g);
do
result=$(multipath -ll "$lun" 2> /dev/null)
echo "$result" | grep " sd" | awk -v nlun="$lun" '{print nlun" "$3" "$2" "$5" "$6" "$7}' >> $tmpfile
done
}
function explain_all () {
results=$(multipath -ll 2> /dev/null)
local lun=""
local count=0
echo "$results" | while read line;
do
if [ "${line:0:2}" == "36" ]; then
lun=$(echo $line | awk '{print $1}')
if [ ! -z "$last_lun" ] && [ "$count" -gt 0 ]; then
echo "$last_lun at $this_inode count is [$count]"
fi
last_lun=$lun
count=0
fi
if [ $(echo $line | grep -c " sd") -eq 1 ]; then
echo "$line" | awk -v nlun="$lun" '{print nlun" "$3" "$2" "$5" "$6" "$7}'
count=$((count+1))
fi
done
echo "$lun at $this_inode count is [$count]"
}
WWIDS=/etc/multipath/wwids
if [ ! -f /etc/multipath/wwids ]; then
echo "/etc/multipath/wwids files not existed"
if [ $(multipath -ll 2>&1 | grep -c "DM multipath kernel driver not loaded") -eq 1 ]; then
echo "DM multipath kernel driver not loaded"
exit 1
fi
fi
explain_all >> $tmpfile
exit 0
最后一行没有值 |
#!/bin/bash
tmpfile=/root/multipath_tmp
rstfile=/root/multipath_rst
[ -e "$tmpfile" ] && rm -rf $tmpfile
[ -e "$rstfile" ] && rm -rf $rstfile
this_inode=$(ifconfig Mgnt-0 | grep "inet " | awk '{print $2}')
function explain_one_foreach () {
for lun in $(cat "$WWIDS" | grep -v ^# | sed s#/##g);
do
result=$(multipath -ll "$lun" 2> /dev/null)
echo "$result" | grep " sd" | awk -v nlun="$lun" '{print nlun" "$3" "$2" "$5" "$6" "$7}' >> $rstfile
done
}
function explain_all () {
multipath -ll > $tmpfile 2> /dev/null
local lun=""
local count=0
while read line;
do
if [ "${line:0:2}" == "36" ]; then
lun=$(echo $line | awk '{print $1}')
if [ ! -z "$last_lun" ] && [ "$count" -gt 0 ]; then
echo "$last_lun at $this_inode count is [$count]"
fi
last_lun=$lun
count=0
fi
if [ $(echo $line | grep -c " sd") -eq 1 ]; then
echo "$line" | awk -v nlun="$lun" '{print nlun" "$3" "$2" "$5" "$6" "$7}'
count=$((count+1))
fi
done < $tmpfile
echo "$lun at $this_inode count is [$count]"
}
WWIDS=/etc/multipath/wwids
if [ ! -f /etc/multipath/wwids ]; then
echo "/etc/multipath/wwids files not existed"
if [ $(multipath -ll 2>&1 | grep -c "DM multipath kernel driver not loaded") -eq 1 ]; then
echo "DM multipath kernel driver not loaded"
exit 1
fi
fi
explain_all >> $rstfile
# cat $rstfile
exit 0
对了 366c2222222222aa95116c76b00000163 sdc 33:0:0:2 active ready running |
https://www.cnblogs.com/Juststudy02/p/9842713.html
The text was updated successfully, but these errors were encountered: