Linux 在bash中退出while循环时丢失变量值
在我的脚本中,我想计算在不同目录中有多少目录和文件。在“assignments”中,我有许多名为“repo1”、“repo2”等的目录。以下是我的代码:Linux 在bash中退出while循环时丢失变量值,linux,bash,shell,while-loop,scope,Linux,Bash,Shell,While Loop,Scope,在我的脚本中,我想计算在不同目录中有多少目录和文件。在“assignments”中,我有许多名为“repo1”、“repo2”等的目录。以下是我的代码: ls -1 assignments | while read -r repoDir do find assignments/"$repoDir" | grep -v .git | grep "$repoDir"/ | while read -r aPathOfRepoDir do BASENAME=`basena
ls -1 assignments | while read -r repoDir
do
find assignments/"$repoDir" | grep -v .git | grep "$repoDir"/ | while read -r aPathOfRepoDir
do
BASENAME=`basename "$aPathOfRepoDir"`
if [[ -d "$aPathOfRepoDir" ]]; then
totalDirectories=$((totalDirectories+1))
elif [[ -f "$aPathOfRepoDir" ]] && [[ "$BASENAME" == *".txt" ]]; then
totalTextFiles=$((totalTextFiles+1))
else
totalOtherFiles=$((totalOtherFiles+1))
fi
done
echo "total directories: $totalDirectories"
echo "total text files: $totalTextFiles"
echo "total other files: $totalOtherFiles"
totalDirectories=0
totalTextFiles=0
totalOtherFiles=0;
done
当while循环完成时,我将丢失这3个变量的值。我知道这是因为while循环是一个子shell,但我不知道如何“存储”父shell的变量值。当我知道这是最后一个“aPathOfRepoDir”时,我考虑在while循环中打印这些消息,但这是一种“便宜”的方式,效率不高。还有别的办法吗
提前感谢管道的右侧在子外壳中运行。子shell变量中的更改不会传播到父shell。使用流程替代:
while read -r aPathOfRepoDir
do
BASENAME=`basename "$aPathOfRepoDir"`
if [[ -d "$aPathOfRepoDir" ]]; then
totalDirectories=$((totalDirectories+1))
elif [[ -f "$aPathOfRepoDir" ]] && [[ "$BASENAME" == *".txt" ]]; then
totalTextFiles=$((totalTextFiles+1))
else
totalOtherFiles=$((totalOtherFiles+1))
fi
done < <(find assignments/"$repoDir" | grep -v .git | grep "$repoDir"/ )
读取时-r
做
BASENAME=`BASENAME“$aPathOfRepoDir”`
如果[-d“$APATHOFROPDIR”];然后
TotalDirectory=$((TotalDirectory+1))
elif[[-f“$aPathOfRepoDir”]]和&[“$BASENAME”==*”.txt”];然后
totalTextFiles=$((totalTextFiles+1))
其他的
totalOtherFiles=$((totalOtherFiles+1))
fi
完成子外壳中管路的右侧。子shell变量中的更改不会传播到父shell。使用流程替代:
while read -r aPathOfRepoDir
do
BASENAME=`basename "$aPathOfRepoDir"`
if [[ -d "$aPathOfRepoDir" ]]; then
totalDirectories=$((totalDirectories+1))
elif [[ -f "$aPathOfRepoDir" ]] && [[ "$BASENAME" == *".txt" ]]; then
totalTextFiles=$((totalTextFiles+1))
else
totalOtherFiles=$((totalOtherFiles+1))
fi
done < <(find assignments/"$repoDir" | grep -v .git | grep "$repoDir"/ )
读取时-r
做
BASENAME=`BASENAME“$aPathOfRepoDir”`
如果[-d“$APATHOFROPDIR”];然后
TotalDirectory=$((TotalDirectory+1))
elif[[-f“$aPathOfRepoDir”]]和&[“$BASENAME”==*”.txt”];然后
totalTextFiles=$((totalTextFiles+1))
其他的
totalOtherFiles=$((totalOtherFiles+1))
fi
完成<这个怎么样:
classify() {
local -A types=([dir]=0 [txt]=0 [other]=0)
local n=0
while read -r type path; do
if [[ $type == d ]]; then
(( types[dir] ++ ))
elif [[ $type == f && $path == *.txt ]]; then
(( types[txt] ++ ))
else
(( types[other] ++ ))
fi
((n++))
done
if [[ $n -gt 0 ]]; then
echo "$1"
echo "total directories: ${types[dir]}"
echo "total text files: ${types[txt]}"
echo "total other files: ${types[other]}"
fi
}
for repoDir in assignments/*; do
find "$repoDir" \
\( ! -path "$repoDir" -a ! -path '*/.git' -a ! -path '*/.git/*' \) \
-printf '%y %p\n' \
| classify "$repoDir"
done
find
可以排除您不想看到的文件
- find还将发出文件类型以简化分类
- “分类”功能将循环查找输出,以统计各种类别李>
- 该函数有助于在单个子shell中本地化所有变量
这个怎么样:
classify() {
local -A types=([dir]=0 [txt]=0 [other]=0)
local n=0
while read -r type path; do
if [[ $type == d ]]; then
(( types[dir] ++ ))
elif [[ $type == f && $path == *.txt ]]; then
(( types[txt] ++ ))
else
(( types[other] ++ ))
fi
((n++))
done
if [[ $n -gt 0 ]]; then
echo "$1"
echo "total directories: ${types[dir]}"
echo "total text files: ${types[txt]}"
echo "total other files: ${types[other]}"
fi
}
for repoDir in assignments/*; do
find "$repoDir" \
\( ! -path "$repoDir" -a ! -path '*/.git' -a ! -path '*/.git/*' \) \
-printf '%y %p\n' \
| classify "$repoDir"
done
find
可以排除您不想看到的文件
- find还将发出文件类型以简化分类
- “分类”功能将循环查找输出,以统计各种类别李>
- 该函数有助于在单个子shell中本地化所有变量
这对于包含换行符但可以更正的文件名很容易受到攻击。对于包含换行符但可以更正的文件名很容易受到攻击。