在 shell 脚本中没有列表的 for 循环
for loop without List in the shell script
我正在阅读来自 OpenFoam 的 shell 脚本 ( /opt/openfoam8/bin/foamCleanPath
)。在这个脚本中,有一段代码:
for dir
do
....
done
我在下面的截图中标记了代码段
但是我想知道为什么它不像for dir in someList
,并且在上面的代码段中没有定义dir
。我应该怎么理解呢?
这里是源代码:
#!/bin/sh
#------------------------------------------------------------------------------
# ========= |
# \ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \ / O peration | Website: https://openfoam.org
# \ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
# \/ M anipulation |
#------------------------------------------------------------------------------
# License
# This file is part of OpenFOAM.
#
# OpenFOAM is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
#
# Script
# foamCleanPath
#
# Description
# Usage: foamCleanPath [-strip] path [wildcard] .. [wildcard]
#
# Prints its argument (which should be a ':' separated path)
# without all
# - duplicate elements
# - elements whose start matches a wildcard
# - inaccessible directories (with the -strip (at your option)
#
# Note
# - this routine will fail when directories have embedded spaces
# - false matches possible if a wildcard contains '.' (sed regex)
# - the wildcards can themselves can be written together and separated
# by colons or whitespace
#------------------------------------------------------------------------------
usage() {
cat <<USAGE
Usage: ${0##*/} [OPTION] path [wildcard1] .. [wildcardN]
options:
-strip remove inaccessible directories
-help print the usage
Prints its argument (which should be a ':' separated list) cleansed from
- duplicate elements
- elements whose start matches one of the wildcard(s)
- inaccessible directories (with the -strip option)
Exit status
0 on success
1 for miscellaneous errors.
2 initial value of 'path' is empty
USAGE
}
error() {
usage 1>&2
exit 1
}
unset strip
# parse options
while [ "$#" -gt 0 ]
do
case "" in
-h | -help)
usage && exit 0
;;
-strip)
strip=true
shift
;;
-*)
error
;;
*)
break
;;
esac
done
[ "$#" -ge 1 ] || error
dirList=""
shift
[ -n "$dirList" ] || exit 2 # quick exit on empty 'dirList'
##DEBUG echo "input>$dirList<" 1>&2
# preserve current IFS and split on colon or whitespace
oldIFS="$IFS"
IFS=': '
# "wildcard1 ... wildcardN" may have been passed as a single parameter
# or may contain ':' separators
set -- $*
# strip out wildcards via sed
while [ "$#" -ge 1 ]
do
wildcard=
shift
##DEBUG echo "remove>$wildcard<" 1>&2
if [ -n "$wildcard" ]
then
dirList=$(echo "$dirList:" | sed -e "s|${wildcard}[^:]*:||g")
fi
done
# split on ':' (and on space as well to avoid any surprises)
IFS=': '
set -- $dirList
##DEBUG echo "intermediate>$dirList<" 1>&2
# rebuild the list from scratch
unset dirList
for dir
do
##DEBUG echo "check>$dir<" 1>&2
#- dirs must exist
if [ -e "$dir" ]
then
#- no duplicate dirs
duplicate=$(echo " $dirList " | sed -ne "s: $dir :DUP:p")
if [ ! "$duplicate" ]
then
dirList="$dirList $dir"
fi
elif [ "$strip" != true ]
then
# Print non-existing directories if not in 'strip' mode.
dirList="$dirList $dir"
fi
done
# split on whitespace
IFS=' '
set -- $dirList
# rejoin on ':'
IFS=':'
dirList="$*"
# restore IFS
IFS="$oldIFS"
##DEBUG echo "output>$dirList<" 1>&2
echo "$dirList"
#------------------------------------------------------------------------------
引用 Bash man page,一个更常见的 shell 实现 /bin/sh
:
for name [ [ in [ word ... ] ] ; ] do list ; done
The list of words following in
is expanded, generating a list of items. The variable name is set to each element of this list in turn, and list is executed each time. If the in
word is omitted, the for
command executes list once for each positional parameter that is set [...]
因此,如果省略 in ...
部分,循环将遍历当前上下文中设置的位置参数(</code>、<code>
、...) .在您的情况下,这将是作为命令行参数给出的 通配符 的列表。
我正在阅读来自 OpenFoam 的 shell 脚本 ( /opt/openfoam8/bin/foamCleanPath
)。在这个脚本中,有一段代码:
for dir
do
....
done
我在下面的截图中标记了代码段
但是我想知道为什么它不像for dir in someList
,并且在上面的代码段中没有定义dir
。我应该怎么理解呢?
这里是源代码:
#!/bin/sh
#------------------------------------------------------------------------------
# ========= |
# \ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \ / O peration | Website: https://openfoam.org
# \ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
# \/ M anipulation |
#------------------------------------------------------------------------------
# License
# This file is part of OpenFOAM.
#
# OpenFOAM is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
#
# Script
# foamCleanPath
#
# Description
# Usage: foamCleanPath [-strip] path [wildcard] .. [wildcard]
#
# Prints its argument (which should be a ':' separated path)
# without all
# - duplicate elements
# - elements whose start matches a wildcard
# - inaccessible directories (with the -strip (at your option)
#
# Note
# - this routine will fail when directories have embedded spaces
# - false matches possible if a wildcard contains '.' (sed regex)
# - the wildcards can themselves can be written together and separated
# by colons or whitespace
#------------------------------------------------------------------------------
usage() {
cat <<USAGE
Usage: ${0##*/} [OPTION] path [wildcard1] .. [wildcardN]
options:
-strip remove inaccessible directories
-help print the usage
Prints its argument (which should be a ':' separated list) cleansed from
- duplicate elements
- elements whose start matches one of the wildcard(s)
- inaccessible directories (with the -strip option)
Exit status
0 on success
1 for miscellaneous errors.
2 initial value of 'path' is empty
USAGE
}
error() {
usage 1>&2
exit 1
}
unset strip
# parse options
while [ "$#" -gt 0 ]
do
case "" in
-h | -help)
usage && exit 0
;;
-strip)
strip=true
shift
;;
-*)
error
;;
*)
break
;;
esac
done
[ "$#" -ge 1 ] || error
dirList=""
shift
[ -n "$dirList" ] || exit 2 # quick exit on empty 'dirList'
##DEBUG echo "input>$dirList<" 1>&2
# preserve current IFS and split on colon or whitespace
oldIFS="$IFS"
IFS=': '
# "wildcard1 ... wildcardN" may have been passed as a single parameter
# or may contain ':' separators
set -- $*
# strip out wildcards via sed
while [ "$#" -ge 1 ]
do
wildcard=
shift
##DEBUG echo "remove>$wildcard<" 1>&2
if [ -n "$wildcard" ]
then
dirList=$(echo "$dirList:" | sed -e "s|${wildcard}[^:]*:||g")
fi
done
# split on ':' (and on space as well to avoid any surprises)
IFS=': '
set -- $dirList
##DEBUG echo "intermediate>$dirList<" 1>&2
# rebuild the list from scratch
unset dirList
for dir
do
##DEBUG echo "check>$dir<" 1>&2
#- dirs must exist
if [ -e "$dir" ]
then
#- no duplicate dirs
duplicate=$(echo " $dirList " | sed -ne "s: $dir :DUP:p")
if [ ! "$duplicate" ]
then
dirList="$dirList $dir"
fi
elif [ "$strip" != true ]
then
# Print non-existing directories if not in 'strip' mode.
dirList="$dirList $dir"
fi
done
# split on whitespace
IFS=' '
set -- $dirList
# rejoin on ':'
IFS=':'
dirList="$*"
# restore IFS
IFS="$oldIFS"
##DEBUG echo "output>$dirList<" 1>&2
echo "$dirList"
#------------------------------------------------------------------------------
引用 Bash man page,一个更常见的 shell 实现 /bin/sh
:
for name [ [ in [ word ... ] ] ; ] do list ; done
The list of words followingin
is expanded, generating a list of items. The variable name is set to each element of this list in turn, and list is executed each time. If thein
word is omitted, thefor
command executes list once for each positional parameter that is set [...]
因此,如果省略 in ...
部分,循环将遍历当前上下文中设置的位置参数(</code>、<code>
、...) .在您的情况下,这将是作为命令行参数给出的 通配符 的列表。