首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >POSIX兼容外壳中的数组

POSIX兼容外壳中的数组
EN

Stack Overflow用户
提问于 2016-02-13 22:14:53
回答 3查看 15.4K关注 0票数 23

根据这是hyperpolyglot.org上的参考资料,可以使用以下语法来设置数组。

代码语言:javascript
复制
i=(1 2 3)

但我得到了一个错误的破折号,这是默认的/bin/sh在Ubuntu,应该是符合POSIX的。

代码语言:javascript
复制
# Trying the syntax with dash in my terminal
> dash -i
$ i=(1 2 3)
dash: 1: Syntax error: "(" unexpected
$ exit

# Working fine with bash
> bash -i
$ i=(1 2 3)
$ echo ${i[@]}
1 2 3
$ exit

参考书是误导还是错误?

如果是,定义数组或列表并符合POSIX的正确方法是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-02-13 22:16:44

Posix不指定数组,因此如果仅限于Posix shell功能,则不能使用数组。

恐怕你的推荐信错了。可悲的是,并不是所有你在互联网上找到的都是正确的。

票数 26
EN

Stack Overflow用户

发布于 2017-06-14 19:38:58

正如里基所说,dash不支持数组。但是,如果您想要编写一个循环,则有一些解决办法。

For循环不会执行数组,但是您可以使用while循环+ read内置器进行拆分。由于dash read内置也不支持分隔符,所以您也必须解决这个问题。

下面是一个示例脚本:

代码语言:javascript
复制
myArray="a b c d"

echo "$myArray" | tr ' ' '\n' | while read item; do
  # use '$item'
  echo $item
done

对此有更深层次的解释:

  • tr ' ' '\n'将允许您在删除空格的地方执行单字符替换&添加换行符--这是读取内置内容的默认标记。
  • read检测到stdin已经关闭时,它将使用一个失败的退出代码退出--这将是当您的输入被完全处理时。
  • 因为echo在输入后会打印额外的换行符,这将允许您处理数组中的最后一个“元素”。

这相当于bash代码:

代码语言:javascript
复制
myArray=(a b c d)

for item in ${myArray[@]}; do
  echo $item
done

如果您想检索n-th元素(假设第2-元素用于示例):

代码语言:javascript
复制
myArray="a b c d"

echo $myArray | cut -d\  -f2 # change -f2 to -fn
票数 20
EN

Stack Overflow用户

发布于 2019-12-16 09:38:41

的确,POSIX sh shell没有与bash和其他shell相同的命名数组,但是sh shell(以及bash和其他shell)可以使用的列表,这是位置参数列表。

此列表通常包含传递给当前脚本或shell函数的参数,但可以使用set内置命令设置其值:

代码语言:javascript
复制
#!/bin/sh

set -- this is "a list" of "several strings"

在上面的脚本中,位置参数$1$2、.被设置为所示的五个字符串。--用于确保您不会意外地设置一个shell选项( set命令也能够这样做)。但是,只有当第一个参数以-开头时,这才是一个问题。

例如,在这些字符串上循环,可以使用

代码语言:javascript
复制
for string in "$@"; do
    printf 'Got the string "%s"\n' "$string"
done

或者更短的

代码语言:javascript
复制
for string do
    printf 'Got the string "%s"\n' "$string"
done

或者只是

代码语言:javascript
复制
printf 'Got the string "%s"\n' "$@"

set对于将全局扩展为路径名列表也很有用:

代码语言:javascript
复制
#!/bin/sh

set -- "$HOME"/*/

# "visible directory" below really means "visible directory, or visible 
# symbolic link to a directory".

if [ ! -d "$1" ]; then
    echo 'You do not have any visible directories in your home directory'
else
    printf 'There are %d visible directories in your home directory\n' "$#"

    echo 'These are:'
    printf '\t%s\n' "$@"
fi

shift内置命令可用于从列表中移除第一个位置参数。

代码语言:javascript
复制
#!/bin/sh

# pathnames
set -- path/name/1 path/name/2 some/other/pathname

# insert "--exclude=" in front of each
for pathname do
    shift
    set -- "$@" --exclude="$pathname"
done

# call some command with our list of command line options
some_command "$@"
票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35385962

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档