在ubuntu中使用/ bin / bash运行grep时,popen错误重定向是意外的

时间:2015-09-02 02:06:55

标签: c++ linux bash shell

我试图解决一个简单的hackerank问题并且我被困住了。 在命令行上执行grep时,我没有问题

function loadImage(src, callback){ var img = $('<img>').on('load', function(){ callback.call(img); }); img.attr('src', src); // get all the captions (should probably be done with variable referring to something about above selector) var allcaptions = $("figure span"); // setTimeout is a hack here, since the ".placeholders" don't exist yet setTimeout(function () { $(".placeholder").each(function (i) { // in each .placeholder, copy its caption's mark-up into it (remove the img first) var caption = allcaptions.eq(i).clone(); // caption.find("img").remove(); $(this).append("<div class='caption'>" + caption.html() + "</div>"); }); }, 500 ); }

结果:(不返回任何内容)

grep -i \"the[^a-z0-9]\" $filename <<< "from fairest creatures we desire increase" 结果:(突出显示的)时钟敲响了两次 我读了这篇文章: Can I open bash from a popen() stream?

我试过用&#34; exec bash -c&#34;前面加上grep命令。和&#34; / bin / bash -c&#34;无济于事。

任何人都可以告诉我为什么我会收到此错误以及如何解决此问题?

sh:1:语法错误:重定向意外

f为空

我的代码:

grep -i \"the[^a-z0-9]\" $filename <<< "the clock struck twice"

2 个答案:

答案 0 :(得分:1)

处理带参数的命令行标志的正常(且几乎是通用的)约定是命令行标志本身后面的单个参数是关联的参数。后续参数可以是其他标志或位置参数。

bash肯定是这样。如果要使用-c命令行标志来执行bash命令,则整个命令必须是-c标志的参数,并且它必须是单个参数。在执行命令之前,后续参数将分配给$0$1等。

所以如果你输入:

bash -c echo foo

你会看到一个空行。你可以这样做:

bash -c 'echo $0' foo

将按预期打印foo“(如果您的期望得到了很好的磨练),但这样做是正常的:

bash -c 'echo foo' 

同样,如果你执行

/bin/bash -c grep -i \"the[^a-z0-9]\" ...

你要求bash执行没有参数的命令grep; -i和后续参数被分配给$0等,但由于这些参数从未被命令引用,这有点无意义。

你的意思是

/bin/bash -c 'grep -i "the[^a-z0-9]" ... '

(你不能反斜杠转义单引号字符串中的任何内容,因此反斜杠被移除。我看不出它们在原始命令行中是如何工作的;目标字符串中没有匹配的双引号。)

显然,here-string(<<<"...poem...")必须是-c的{​​{1}}参数的一部分,而不是/bin/bash解释的命令行的一部分。 }。 popen使用popen来执行提供的命令行,sh很可能无法识别“here-string”语法;这是一个bash扩展。由于sh中的<<<并不特殊,因此sh通常被解释为here-doc,后面必须跟一个分隔符字符串。它不能跟<<重定向;因此出现“意外重定向”错误。当您将<后面的单词设置为很长时,在解析错误的重定向之前,您显然会触发“文件名太长”错误。这只是猜测;我没有重现这个问题。

报价对你来说很烦人。如上所述,单引号字符串中的<<<没有问题,但您必须反斜杠双引号以符合C字符串文字语法。不幸的是,字符串文字包含单引号,其中第一个将被解析为关闭"中的单引号。并且没有办法在bash单引号字符串中反斜杠转义任何内容,甚至没有单引号。

唯一可行的方法是用序列bash -c '表示每个'(在C字符串中需要'\'')。在该序列中,第一个和最后一个'关闭并重新打开单引号字符串,中间的'\\''是反斜杠转义的'。< / p>

最后三个笔记:

  1. \'对您的命令没有影响,因为从未定义$filename。如果它被定义,它将产生各种错误;因为它没有被定义而扩展没有被引用,所以它只是从命令行中消失了,但是最好不要把它放在那里。

  2. 使用反斜杠换行符可以在一行到另一行继续使用C字符串,如示例代码中所示,但不会在字符串中插入换行符。因此,提供给$filename的输入将是一行。我认为这不是你的意思。

  3. 你必须引用here-string; here-strings的语法是grep后跟一个“单词”;如果你不在它周围加上引号,你最终只会将第一个空格的部分视为输入。

答案 1 :(得分:0)

我认为你的输入没有被引用。

string cmd_string = "/bin/bash -c grep -i \"the[^a-z0-9]\" $filename <<< "+ \" + input + \";