KSH,读取在管道中使用

时间:2017-07-30 10:35:28

标签: ksh pipeline heredoc

我正在尝试学习Korn Shell中的文档IO重定向。 我使用“read”内置来测试概念。

我写了一个示例程序如下

#!/usr/bin/ksh

cat << ONE | wc -l | read word | if [ $word -eq 1 ]; then cat << TWO ; fi  | wc -l | read word | if [ $word -eq 2 ]; then cat << THREE ; fi 
1
ONE
1
2
TWO
1
2
3
THREE

我希望输出为:

1
2
3

但输出是

[: argument expected

我认为$ word变量是空的。

然后我重写了下面的程序,工作正常:

cat << ONE | wc -l | { read word ; if [ $word -eq 1 ]; then cat << TWO ; fi ;} | wc -l | { read word ; if [ $word -eq 2 ]; then cat << THREE ; fi ;}
1
ONE
1
2
TWO
1
2
3
THREE

输出符合预期:

1
2
3

我的问题是关于第一个片段:

  • 为什么管道中的“读取字”命令不更新字 shell中的变量和后续命令无法使用 它。
  • 此外,“读取字”不会向标准输出写入任何内容,因此
    在管道中使用它是不对的,但我想检查一下。
  • 但是,“读取单词”后的命令不会读取任何内容 从标准输入来看应该没问题。

1 个答案:

答案 0 :(得分:1)

请记住,管道的每一侧(|)都是一个单独的shell会话。

在您第一次尝试时,您有... | wc -l | read word | if ...,所以虽然wc -l的结果将被读取并存储在下一个shell会话的变量word中,但此变量不会传递给下一个shell会话。由于变量word现在未定义,因此您的语句if [ $word -eq 1 ]变为if [ -eq -1 ],因此错误。

在您的第二次尝试中,您的{ read word ; if [ $word -eq 1 ]; then cat << TWO ; fi ;}构造表示单个shell会话,其中变量word已初始化(结果为wc -l),并且因为这仍然是单个shell变量现在可以在if/then块中使用。