简体   繁体   English

shell 脚本中没有 List 的 for 循环

[英]for loop without List in the shell script

I am reading a shell script( /opt/openfoam8/bin/foamCleanPath ) from OpenFoam .我正在阅读来自 OpenFoam 的 shell 脚本( /opt/openfoam8/bin/foamCleanPath In this script, there is a code segment:在这个脚本中,有一段代码:

for dir
do
....
done

I marked the code segment in the following screenshot.我在以下屏幕截图中标记了代码段。
But I am wondering why it is NOT like for dir in someList , and there is no definition of dir in the above code segment.但我想知道为什么它不像for dir in someList ,并且上面的代码段中没有dir的定义。 How should I understand it?我应该怎么理解? 在此处输入图像描述

Here is the source code:这是源代码:

#!/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 "$1" in
    -h | -help)
        usage && exit 0
        ;;
    -strip)
        strip=true
        shift
        ;;
    -*)
        error
        ;;
    *)
        break
        ;;
    esac
done


[ "$#" -ge 1 ] || error

dirList="$1"
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=$1
    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"

#------------------------------------------------------------------------------



To quote the Bash man page , one of the more common shells implementing /bin/sh :引用Bash 手册页,这是实现/bin/sh的更常见的 shell 之一:

for name [ [ in [ word... ] ]; ] do list; done
The list of words following in is expanded, generating a list of items. in之后的单词列表被扩展,生成项目列表。 The variable name is set to each element of this list in turn, and list is executed each time.变量依次设置到这个list的每个元素,每次都会执行list If the in word is omitted, the for command executes list once for each positional parameter that is set [...]如果省略in,则for命令对设置的每个位置参数执行一次list [...]

Thus, if you omit the in... part, the loop will iterate over the positional arguments ( $1 , $2 , ...) which are set in the current context.因此,如果您省略in...部分,循环将遍历在当前上下文中设置的位置 arguments ( $1 , $2 , ...)。 In your case, this would be the list of wildcards given as command line arguments.在您的情况下,这将是作为命令行 arguments 给出的通配符列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM