怎么设置 - 有什么用?

时间:2013-06-24 16:10:17

标签: linux shell set

我已经编写了一个相当广泛的shell脚本和我在stackoverflow上进行研究所获得的一些功能。我实施但未完全理解的一件事是使用set -- something

我已经阅读了help set命令,但我仍然无法理解它在以下场景中的实现方式:

#!/bin/sh

params="$(getopt abc:d: $*)"

如果我那么

set -- $params

set到底在做什么?

2 个答案:

答案 0 :(得分:3)

bash man page明确涵盖了这一点。

  

-

     

如果此选项后面没有参数,则取消设置位置参数。否则,位置参数将设置为参数,即使其中一些参数以“ - ”开头。

答案 1 :(得分:3)

简而言之,set -- "$(getopt abc:d: $*)"的作用是创建错误。这不是set特有的,尽管使用getopt一定是偶然的;但是,使用$*也是通用的。

请考虑以下事项:

./yourscript -f"./filename with spaces"

$*将所有参数压缩成一个字符串 - 之后,由于它没有引用,这些参数根据IFS./filename with spaces的内容再次拆分为三个参数: ./filenamewithspaces。不要那样做。相反,请遵循http://mywiki.wooledge.org/BashFAQ/035的做法(是的,它被称为BashFAQ,但它涵盖了POSIX兼容的机制以及特定于bash的机制)。

那就是说,要讨论它的目的是什么,以下是一个工作范例:

$ getopt abc:d: -a -c foo bar baz
 -a -c foo -- bar baz

...以下是即使不使用getopt$*被破坏的原因示例(请参阅单个参数foo bar如何分成两个单独的部分,{ {1}}和foo):

bar

...以下是为什么$ getopt abc:d: -a -c "foo bar" baz -a -c foo bar -- baz 不应该与字符串拆分结合使用的示例,这就是不加引号的扩展(例如set --)被拆分成的方式多个参数:

$params

相反,管理要放入参数列表的项列表的正确方法是使用数组 - 一个bash扩展,因为POSIX sh只是允许任何正确的方法来执行此操作:

$ params='-f "foo bar"'
$ set -- $params
$ printf '<%s> ' "$@"; echo
<-a> <"foo> <bar">

在任何一种情况下,参数向量($ params=( -f "foo bar" ) $ set -- "${params[@]}" $ printf '<%s> ' "$@"; echo <-a> <foo bar> )都会被$@的新内容更改,只能在所有可选参数之后放置位置参数,由set --分隔。然而,它发生了不正确的变化:多字参数被字符串拆分并错误地重新组合。再次,请参阅链接的常见问题解答以了解处理此问题的正确方法。