从使用 args 调用的函数内部获取文件参数

从使用 args 调用的函数内部获取文件参数

所以情况是这样的...我有 shell 脚本文件,其中包含函数以及其他命令,例如...

#!/bin/sh

myFunc() {
  for arg in "$@"; do
    # ... do something with every arg passed to myFunc
  done
}

# ... do something

myFunc func-arg-1

# ... do something

myFunc func-arg-2 func-arg-1

# ... do something

是否可以获取从内部传递给文件的参数myFunc

答案1

如果您可以使用 Bash/Ksh/Zsh,则可以将脚本的参数放入数组中并从函数内访问它们:

#!/bin/bash
args=( "$@" )
func() {
    local x
    for x in "$@"; do
        echo "$x is an argument to the function"
    done
    for x in "${args[@]}"; do
        echo "$x is an argument to the script"
    done
}
func bla

在 POSIX shell 中,除了单个参数列表之外没有其他数组。如果您需要区分脚本参数和函数参数,您可以手动将脚本的参数传递给函数,并使用一些分隔符:

#!/bin/sh
delim=:::
func() {
    delim_seen=0
    for k in "$@"; do
        if [ "$k" = "$delim" ]; then
            delim_seen=1
            continue;
        elif [ "$delim_seen" = 0 ]; then
            echo "$k is an argument to the function only"
        else
            echo "$k is an argument to the script"
        fi
    done
}
func bla "$delim" "$@"

当然,如果实际参数本身包含分隔符字符串,这将会失败。Stéphane 显式传递计数的解决方案当然更好,因为它不存在这个问题。

但是,无论采用哪种方法,随机访问参数几乎都是不可能的。这也适用于同时处理两个列表,即使在每个列表中按顺序处理也是如此。如果您需要这样做,我真的建议切换到一些功能更丰富的 shell,或实际的编程语言(Perl、Python 等)。


如果脚本采用的参数只是可选开关(例如-i、 或-k foo),则可以getopts在调用函数之前将它们解析为单独的变量。或者,如果函数的参数更像开关,请将它们放在单独的变量中。

而且,如果函数的参数中有一些已知的结构,并且它们被认为是“好的”字符串而不是任意文件名,那么您可能能够将它们打包在单个字符串中,再次可能使用一些分隔符(字符)不能出现在值本身中。然后应用模式匹配和参数扩展来处理批次。 (或者甚至,天堂不允许,故意调用分词。)这不会很漂亮,但可能是可行的,这在很大程度上取决于细节。

答案2

在函数内部, in sh,位置参数 ( $1, $2..., $@, $*) 是函数本身的位置参数,脚本的位置参数(如果从另一个函数中调用,则为父函数的位置参数)不再可访问。

因此,您需要以其他方式将这些参数传递给函数。

不支持数组变量并没有帮助sh,这使得存储任意字符串列表变得困难。

除了其他人已经建议的解决方案之外,您还可以这样做:

#! /bin/sh -

myFunc() {
  n="$(( $# - $1 - 1 ))" i=0; shift
  for arg do
    case "$i" in
      ("$n") break;;
      (0) shift "$n";; # on first pass, remove the function arguments from "$@"
    esac
    i="$(( i + 1 ))"
    # ... do something with every "$arg" passed to myFunc and with "$@"
  done
}

并调用myFunc为:

myFunc "$#" args for myFunc "$@"

答案3

只需将它们传递给函数即可:

myFunc func-arg-2 func-arg-1 "$@"

相关内容