Bash:如何从参数设置变量,并使用默认值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16074786/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 23:36:45  来源:igfitidea点击:

Bash: How to set a variable from argument, and with a default value

bashshellunix

提问by Steven Lu

It is pretty clear that with shell scripting this sort of thing can be accomplished in a huge number of ways (more than most programming languages) because of all the different variable expansion methods and programs like testand [and [[, etc.

很明显,由于所有不同的变量扩展方法和程序,如testand[[[等,使用 shell 脚本可以通过多种方式(比大多数编程语言更多)来完成这类事情。

Right now I'm just looking for

现在我只是在寻找

DIR= or .

Meaning, my DIR variable should contain either what is specified in the first arg or the current directory.

意思是,我的 DIR 变量应该包含在第一个 arg 或当前目录中指定的内容。

What is the difference between this and DIR=${1-.}?

这和 有DIR=${1-.}什么区别?

I find the hyphen syntax confusing, and seek more readable syntax.

我发现连字符语法令人困惑,并寻求更具可读性的语法。

Why can't I do this?

为什么我不能这样做?

DIR="" || '.'

I'm guessing this means "if $1 is empty, the assignment still works (DIR becomes empty), so the invalid command '.' never gets executed."

我猜这意味着“如果 $1 为空,则赋值仍然有效(DIR 变为空),因此无效命令 '.' 永远不会被处决。”

回答by rob mayoff

I see several questions here.

我在这里看到几个问题。

  1. “Can I write something that actually reflects this logic”

    Yes. There are a few ways you can do it. Here's one:

    if [[ "" != "" ]]; then
        DIR=""
    else
        DIR=.
    fi
    
  2. “What is the difference between this and DIR=${1-.}?”

    The syntax ${1-.}expands to .if $1is unset, but expands like $1if $1is set—even if $1is set to the empty string.

    The syntax ${1:-.}expands to .if $1is unset or is set to the empty string. It expands like $1only if $1is set to something other than the empty string.

  3. “Why can't I do this? DIR="$1" || '.'

    Because this is bash, not perl or ruby or some other language. (Pardon my snideness.)

    In bash, ||separates entire commands (technically it separates pipelines). It doesn't separate expressions.

    So DIR="$1" || '.'means “execute DIR="$1", and if that exits with a non-zero exit code, execute '.'”.

  1. “我能写出真正反映这种逻辑的东西吗?”

    是的。有几种方法可以做到。这是一个:

    if [[ "" != "" ]]; then
        DIR=""
    else
        DIR=.
    fi
    
  2. “这和这有什么区别DIR=${1-.}?”

    语法${1-.}扩展为.if$1未设置,但扩展为$1if$1设置 - 即使$1设置为空字符串。

    语法${1:-.}扩展为.if$1未设置或设置为空字符串。它$1仅在$1设置为空字符串以外的内容时才会扩展。

  3. “为什么我不能这样做? DIR="$1" || '.'

    因为这是 bash,而不是 perl 或 ruby​​ 或其他一些语言。(原谅我的冷漠。)

    在 bash 中,||分隔整个命令(从技术上讲,它分隔管道)。它不分离表达式。

    所以DIR="$1" || '.'意思是“执行DIR="$1",如果以非零退出代码退出,则执行'.'”。

回答by Vaughn Cato

How about this:

这个怎么样:

DIR=.
if [ $# -gt 0 ]; then
  DIR=
fi

$#is the number of arguments given to the script, and -gtmeans "greater than", so you basically set DIRto the default value, and if the user has specified an argument, then you set DIRto that instead.

$#是给脚本的参数数量,-gt意思是“大于”,所以你基本上设置DIR为默认值,如果用户指定了一个参数,那么你设置DIR为那个。

回答by icosabit

I use a simple helper function to make such assignments look cleaner. The function below accepts any number of arguments, but returns the first one that's not the empty string.

我使用一个简单的辅助函数来使这些分配看起来更清晰。下面的函数接受任意数量的参数,但返回第一个不是空字符串的参数。

default_value() {
    # Return the first non-empty argument
    while [[ "" == "" ]] && [[ "$#" -gt "0" ]]; do
        shift
    done
    echo 
}
x=$(default_value "" 0)