ksh88 中可以使用 Here-Strings 吗?

ksh88 中可以使用 Here-Strings 吗?

我想从 ksh 脚本中 3 个不同变量中的一个变量中提取 3 个单词。我在 ksh93 上使用了这条线,效果很好:

read A B C <<< $line

在 ksh88 上运行上述命令时出现此错误:

syntax error at line ## : '<' unexpected

如何在 ksh88 上执行相同的操作?

答案1

ksh88不,这里的字符串在和上不可用pdksh。然而,在最近的ksh93(原始 AT&T Korn Shell)和mksh(目前正在积极开发的pdksh衍生产品)上,它是可用的。

<<<ksh93mksh、 GNUbashzsh.

你的具体问题...

read A B C <<< $line

…可以用这个解决(Korn shell):

print -r -- $line |&
read -p A B C

您也可以使用这个(POSIX shell),但它有 tmpfile 性能损失(另一方面,<<<也可能有):

read A B C <<EOF
$line
EOF

但是,如果您只想拆分单词:

set -A arrname -- $line

然后使用${arrname[0]}代替$A${arrname[1]}代替$B。只是它不会在分裂到三个元素时停止,所以如果$line是“ foo bar baz bla”,$C将包含“baz bla”,而${arrname[2]}有“baz”并且${arrname[3]}有“bla”。

不过,如果您不需要位置参数,您可以这样做

set -- $line
A=$1; shift
B=$1; shift
C=$*

但是,如果单词少于三个,则会导致错误(如果不确定,请检查,shift或者首先使用(可能会更慢)进行检查)。$line$#[[ $line = *' '*' '[! ] ]]

请注意,这set … $line也会进行通配符(感谢 Stéphane 提醒我们),因此您需要set -o noglob之前(通常之后可能会恢复之前的状态set +o noglob)。

完全披露:我是mksh开发人员。

答案2

不,here-strings 来自zsh1991 年的 2.0(和/或 的 Unix 端口rc,他们各自的作者在那时交换了想法,目前尚不清楚两人中哪一个有这个想法或首先将其包含在他的 shell 中)。

它在 2.05b (2002) 中添加到 bash,在 m+ (2002) 中添加到 ksh93,在 R33 (2008) 中添加到 mksh,在 2.7 (2009) 中添加到 yash。

ksh88 没有获得任何新功能。

这里的文档 ( <<) 本身来自 70 年代末的 Bourne-shell。

read A B C读一逻辑的以一种非常特殊的方式将行插入A,BC变量(稍微不那么特别,$IFS它的默认值仅包含 IFS 空白字符1),反斜杠充当转义和行继续字符,这将C变得非常复杂以及。如果没有的话做同样的事情read会非常困难。

无论如何,这里的<<<与 一样<<,只有语法差异。

read A B C << EOF
$var
EOF

完全一样

read A B C <<< "$var" # note that some versions of bash need the quotes

在所有贝壳中。对于这两种情况,shell 都会创建一个已删除的临时文件,其中包含内容和一个附加换行符(尽管有些 shell 使用管道代替)。然后read读一逻辑的行(可能在几个以反斜杠继续的物理行上)并使用其复杂的规则填充变量。

$var它仅分配to的前 3 个字(SPC/TAB 分隔)$A$B并且 $C如果

  • $IFS仍然包含其默认值
  • 该变量不包含反斜杠和换行符
  • 该变量仅包含 3 个单词。

对于前三个词,你可以这样做:

function split_into {
  typeset words IFS v i=0
  set -o noglob

  set -A words -- $1; shift
  for v do
    eval "$v=\${words[i]}"
    ((i += 1))
  done
}

split_into "$var" A B C
  
  

^IFS 空白字符,每个 POSIX 是在语言环境中分类的字符[:space:],并且恰好$IFS在 ksh88(POSIX 规范所基于的)和大多数 shell 中,这仍然限于 SPC、TAB 和 NL。我发现在这方面唯一符合 POSIX 标准的 shell 是yash.ksh93并且bash(自 5.0 起)还包括其他空格(例如 CR、FF、VT...),但仅限于单字节空格(请注意某些系统(如 Solaris),其中包括单字节的不间断空格在某些地区)

相关内容