首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >过滤管道而不丢失全部内容

过滤管道而不丢失全部内容
EN

Stack Overflow用户
提问于 2013-01-02 19:30:29
回答 3查看 135关注 0票数 0

标题可能很模糊,但我有一个很好的例子:

代码语言:javascript
复制
echo "Test message:\nThis is a line.\nAnd this is another." | nail -s "`tail -1`" joe@localhost

这里的目标是将回声的内容作为消息正文发送,并使用最后一行作为主题。然而,当我这样做的时候,我失去了身体。

代码语言:javascript
复制
echo "Test message:\nThis is a line.\nAnd this is another." | nail joe@localhost

工作正常,但没有主题。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-01-02 19:57:52

您可以使用命名管道来完成此操作,这在以下位置有效:

代码语言:javascript
复制
mkfifo subj.fifo

echo "Test message:\nThis is a line.\nAnd this is another." |
  tee >(tail -n1 > subj.fifo) | mail -s "$(< subj.fifo)" joe@localhost

rm subj.fifo

注意:如果你使用头部而不是尾部,你需要让tee忽略SIGPIPE信号,例如trap '' PIPE

票数 2
EN

Stack Overflow用户

发布于 2013-01-02 20:00:53

因为你的主题出现在最后一行,所以你必须缓冲所有的行(否则,就无法决定哪一行是最后一行)。将主题放在第一行会容易得多。管他呢。以下是一种可能的方法,使用bash4.0中出现的mapfile

代码语言:javascript
复制
printf "%s\n" "Line one in the body of message" "Line two in the body of message" "Subject in the last line" | {
    mapfile -t array
    nail -s "${array[@]: -1}" joe@localhost < <(printf "%s\n" "${array[@]:0:${#array[@]}-1}")
}

如果您决定将主题放在第一行,这就简单多了(当然,只需要一个管道,除了主题,没有无关的subshell或缓冲区):

代码语言:javascript
复制
printf "%s\n" "Subject in the first line" "Line one in the body of message" "Line two in the body of message"  | { read -r subject; nail -s "$subject" joe@localhost; }
票数 2
EN

Stack Overflow用户

发布于 2013-01-02 19:41:02

tail将丢弃最后一行之前的行。您可以使用临时文件,或者将主题放在第一位而不是最后。无论哪种方式,如果没有一个像tee一样的协作程序,管道就不可能既消耗又保持一条线路。

代码语言:javascript
复制
#!/bin/sh
# use first line as subject, args are recipients
# stdin is message body
read subj
( echo "$subj"; cat ) | nail -s "$subj" "$@"
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14121264

复制
相关文章

相似问题

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