为什么 $# 在我的函数中总是 0?

dev*_*os1 6 shell bash parameter

Bash 快把我逼疯了。我无法弄清楚为什么以下内容(也不是我从示例中逐字复制和粘贴的数十种变体中的任何一种)都无法正常工作:

#!/bin/bash

echo $#

function main {
    if (( $# < 1 )); then
        usage
    fi

    echo "good"
}

function usage {
    echo "Usage: $0 <outputdir>"
    exit 1
}

main
Run Code Online (Sandbox Code Playgroud)

由于某种原因,参数检查每次都失败,即使我传递了一个参数并且可以清楚地看到$#按预期设置。

Gil*_*il' 11

您正在main不带参数地调用该函数。所以$#在主函数中始终为0。

每个函数实例都有自己的参数。(“实例”的意思是,如果功能启动多次(通过递归调用),每次调用都有自己的参数。)的位置参数$1$2等等,以及相关的参数$#$*并且$@是指在传递的参数函数调用。例如,如果您main foo barmain函数内部调用then的值$1将是foo, 的值$#将是 2 等等。

如果要将脚本的参数传递给函数,请使用"$@". 此构造扩展为传递给脚本(或函数,如果在函数内部调用)的参数列表。请注意,与通常使用双引号发生的情况不同,参数是单独传递的,"$@"是字符串列表而不是单个字符串。双引号是必需的,否则参数不会按原样传递,而是被视为以空格分隔的文件名模式列表。

function main {
  if (( $# < 1 )); then
    usage
  fi
  echo "good"
}
main "$@"
Run Code Online (Sandbox Code Playgroud)


Pau*_*ida 7

这应该有效:

#!/bin/bash
set -x
NARGS=$#

function main {
    if [ $NARGS -lt 1 ]; then
        usage
    fi

    echo good
}

function usage {
    echo "Usage: $0 <outputdir>"
    exit 1
}

main
Run Code Online (Sandbox Code Playgroud)

我是set -x故意离开那里的。调试这些错误很有用。如果您不向main函数传递任何参数,$#则在其内部变为 0(在条件中替换$NARGS为以查看此内容)。$#if

  • 我也不知道,因此`set -x` 的用处:) (2认同)