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

Eli*_* G. 2 linux shell bash posix

所以这就是情况......我有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
Run Code Online (Sandbox Code Playgroud)

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

ilk*_*chu 5

如果您可以使用 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
Run Code Online (Sandbox Code Playgroud)

在 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" "$@"
Run Code Online (Sandbox Code Playgroud)

当然,如果实际参数本身包含分隔符字符串,这将失败。Stéphane 明确传递计数的解决方案当然更好,因为它没有那个问题。

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


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

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