多行,双引号字符串将触发后续的单引号命令的历史扩展,该命令将通过管道传递到该单引号 [英] Multi-line, double quoted string triggers history expansion on subsequent single-quoted commands it gets piped to

查看:92
本文介绍了多行,双引号字符串将触发后续的单引号命令的历史扩展,该命令将通过管道传递到该单引号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是GNU bash版本4.3.11.

I am on GNU bash, version 4.3.11.

说我要在文件上打印唯一的行.我正在使用这种方法,该方法在文件上效果很好:

Say I want to print unique lines on a file. I am using this approach, which works well on a file:

$ cat a
9
10
9
11
$ awk '!seen[$0]++' a
9
10
11

但是,如果我从stdin获得输入,在多行中使用双引号并将其管道连接到awk,则会失败:

However, if I get the input from stdin, using double quotes in a multi-line and piping to awk, it fails:

$ echo "9
> 10
> 9
> 11" | awk '!seen[$0]++'
bash: !seen[$0]++': event not found

也就是说,bash尝试扩展命令seen,这当然是不知道的,因为它是一个变量名.但这不应该发生,因为该命令位于单引号内.

That is, bash tries to expand the command seen, which of course does not know because it is a variable name. But it shouldn't happen, since the command is placed within single-quotes.

echo效果很好:

$ echo '9
> 10
> 9
> 11' | awk '!seen[$0]++'
9
10
11

有趣的是,它在单引号中也能很好地工作:双引号:

The funny thing is that it also works well on a single-line input that is double-quoted:

$ printf "9\n10\n9\n11" | awk '!seen[$0]++'
9
10
11

我想知道,即使命令本身使用单引号,如果Bash在mutiline输入之后发生,为什么Bash也会尝试扩展历史记录.

I wonder why is Bash trying to expand history if it occurs after a mutiline input, even though the command itself uses single-quotes.

其他注意事项:

介于两者之间的管道不能解决问题,或者:

Having a pipe in between does not fix it, either:

$ echo "9
> 10
> 9
> 11" | cat - | awk '!seen[$0]++'
bash: !seen[$0]++': event not found

并设置 set +H会关闭历史记录,因此效果很好,因为它不会尝试扩展任何内容:

And setting set +H turns history off, so it works well because it does not try to expand anything:

$ set +H
$ echo "9
> 10
> 9
> 11" | awk '!seen[$0]++'
9
10
11

我在如何解决Bash命令中的错误"bash:!d':未找到事件"时,通过rici的规范回答,并且发现了许多可能的原因,但没有一个与该行为匹配.

I went through the canonical answer by rici on how to address error "bash: !d': event not found" in Bash command substitution and found many possible reasons, but none matches this behaviour.

推荐答案

这不是错误.

在bash-bugs邮件列表中问了这个问题之后,我得到了以下答案:

After asking this in the bash-bugs mailing list, I got the following answer:

历史扩展明确地是面向行的.

History expansion is explicitly line-oriented.

它不知道shell状态,尤其是shell引用状态, 跨越线.

It doesn't know about shell state, especially shell quoting state, that spans lines.

它确实知道在整个 大量的Unix实用程序-自从历史和阅读以来 库在外壳程序外部使用-且双引号 引入带引号的字符串,其中单引号不重要 并且不要抑制历史扩展.

It does know about vaguely shell-like quoting that's common across a large set of Unix utilities -- since the history and readline libraries are used outside the shell -- and that a double quote introduces a quoted string in which single quotes are not significant and don't inhibit history expansion.

这篇关于多行,双引号字符串将触发后续的单引号命令的历史扩展,该命令将通过管道传递到该单引号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆