linux - 编写同时接受管道输入和参数的 Shell 函数

标签 linux function pipe stdin ksh

我正在尝试编写一个调用 logAction 的函数,专门用于 Ksh,它从管道读取输入并在同一个函数调用中接受参数。在谷歌和类似网站上搜索 2 周以来,我一直在尝试对此进行调试。

我尝试创建的函数的目的是为我开发的其他脚本简化将输出记录到日志文件的过程。我打算在各种情况下使用该命令,但最容易描述和说明我正在尝试的 2 个类似于以下内容:

语法示例 1:

logAction 1 "Script executed some action."

语法示例 2:

COMMAND1 | COMMAND2 | logAction 1

如您所见,我希望能够将预期的日志信息作为参数或通过管道作为标准输入传递给函数,以便捕获命令序列的输出。第三种情况是在管道输出之前添加一些文本,即

语法示例 3:

COMMAND1 | COMMAND2 | logAction 1 "This is the output:  "

下面的输出说明了使用示例 3 中的语法的结果:

[2015/12/28 10:20:32] This is the output:  <Output from COMMAND1 | COMMAND 2>

这是我要创建的函数的基本框架。

function logAction {
  while read -t 0 -u 0 stdinput
  do
    echo "StdInput:'$stdinput'"
    pipedinput=$stdinput
  done
  pipedinput=${pipedinput:-}

  case $1 in
    1)  #Output text only to log file
        output=$(echo "$pretag ${@:2} $pipedinput")
        echo $output >> $LOG
    2)  #Output text to screen and log file
        output=$(echo "$pretag ${@:2} $pipedinput")
        echo $output
        echo $output >> $LOG
    3)  
        ....
  esac
  unset pipedinput
}

最初,我没有为 read 命令提供 -t 参数,函数会暂停执行,直到用户输入 CTRL-D 表示 EOF。但是,就我的目的而言,此功能旨在进行静默操作,不应请求用户输入。在 read 命令中添加 -t 0 参数会告诉 read 命令超时 0 秒,而不是等待来自键盘的 EOF

这解决了某些情况下的问题;但是,read 命令在与 cat 命令一起使用时不会捕获任何输入,如下所示:

cat somefile.txt | logAction 1
cat somefile.txt | awk '{ a=a" "$1 }END{ print a }' | logAction 1

但使用 echo 似乎有效:

echo "ab bc cd de ef fg gh" | logAction 1 "This is the output: "

我已经能够通过将超时的 0 更改为 0.1(即 read -t 0.1)使其与 cat 一起工作,但我担心这是一个肮脏的解决方案。这似乎表明存在竞争条件,即在管道完成输出并关闭之前执行 read 命令。这不是我所期望的,因为我认为管道序列中的前一个命令必须在执行后续命令之前完成执行。

有没有办法告诉 read 命令忽略来自键盘的标准输入并使用管道中前面命令的标准输出?我试图告诉它使用 FD0(我认为是来自管道的标准输出,但它似乎也连接到键盘)和 -u 0争论,但这似乎没有用。

最佳答案

试试这个:

#!/bin/ksh

function log 
{
    ARG1=$1
    ARG2=$2

    if [ ! -t 0 ] 
    then
        INPUT=$(cat)
    else
        INPUT=""
    fi  

    echo "<datetime>" ${ARG2}${INPUT}
}

log 1 "Script executed some action."

echo "<data from pipe>" | log 2 "this is the output: "

echo "<data from pipe>" | cat | log 2 "this is the output: "

输出:

<datetime> Script executed some action.
<datetime> this is the output: <data from pipe>
<datetime> this is the output: <data from pipe>

关于linux - 编写同时接受管道输入和参数的 Shell 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34497884/

相关文章:

linux - 使用Izpack在RHEL版本的基础上复制文件

linux - 如何从命令行获取 nvidia 驱动程序版本?

jquery - 我怎样才能把这个 jQuery 片段写得更漂亮

javascript - 在 JavaScript 中调用闭包时,是否在输入闭包代码时创建了一个新的执行上下文?

bash 命令在管道时保留颜色

具有日志功能的 c Pipes shell 守护进程无法正常工作

c - 进程通信: send * commands,为什么循环

linux函数setenv和putenv

javascript - .onclick 按钮不执行功能

javascript - Node js 和 Apache 并行吗?