gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 12:29:22 25 4
gpt4 key购买 nike

我正在尝试解决一个简单的黑客问题,但我被卡住了。
在命令行上执行 grep 时,我没有问题
grep -i \"the[^a-z0-9]\" $filename <<< "from fairest creatures we desire increase"
结果:(不返回任何内容)
grep -i \"the[^a-z0-9]\" $filename <<< "the clock struck twice"结果:(突出显示的)时钟敲响了两次
我读了这篇文章:
Can I open bash from a popen() stream?

我试过在 grep 命令前面加上“exec bash -c”和“/bin/bash -c”但无济于事。

谁能告诉我为什么我会收到这个错误以及如何解决它?

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

f 为空

我的代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include<cmath>
using namespace std;
int main(){

/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int MAX_BUFFER =2048;
string output;
char fileInput [MAX_BUFFER];
// string input(istreambuf_iterator<char>(cin), {});

string input =" From fairest creatures we desire increase ,\
That thereby beauty's rose might never die,\
But as the riper should by time decease,\
His tender heir might bear his memory:\
But thou contracted to thine own bright eyes,\
Feed'st thy light's flame with self-substantial fuel,\
Making a famine where abundance lies,\
Thy self thy foe, to thy sweet self too cruel:\
Thou that art now the world's fresh ornament,\
And only herald to the gaudy spring,\
Within thine own bud buriest thy content,\
And tender churl mak'st waste in niggarding:\
Pity the world, or else this glutton be,\
To eat the world's due, by the grave and thee.\
When forty winters shall besiege thy brow,\
And dig deep trenches in thy beauty's field,\
Thy youth's proud livery so gazed on now,\
Will be a tattered weed of small worth held:\
Then being asked, where all thy beauty lies,\
Where all the treasure of thy lusty days;\
To say within thine own deep sunken eyes,\
Were an all-eating shame, and thriftless praise.\
How much more praise deserved thy beauty's use,\
If thou couldst answer 'This fair child of mine\
Shall sum my count, and make my old excuse";
string cmd_string = "/bin/bash -c grep -i \"the[^a-z0-9]\" $filename <<< "+input;
//cout<<cmd_string.c_str();
FILE *f=popen(cmd_string.c_str(),"r");
while (!feof(f))
{
if (fgets(fileInput, MAX_BUFFER, f) != NULL)
{
cout<<" line 1"<<fileInput[0];
output+=fileInput;
}
else
{

cout<<"f is null"<<endl;
}
}
pclose(f);

cout<< output;
return 0;

}

最佳答案

处理带参数的命令行标志的正常(并且几乎通用)约定是,命令行标志本身后面的单个参数是相关联的参数。后续参数是其他标志或位置参数。
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 的一部分。论据 /bin/bash而不是 popen 解释的命令行的一部分. popen用途 sh执行提供的命令行,很有可能是 sh无法识别“here-string”语法;这是一个 bash 扩展。因为 <<<不是特别在 sh , <<通常被解释为here-doc,后面必须跟一个分隔符字符串。后面不能跟 <重定向;因此出现“意外重定向”错误。当您在 <<< 后面打字时很长,您显然在解析错误的重定向之前触发了“文件名太长”错误。这只是一个猜测;我没有重现问题。

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

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

最后三点说明:
  • $filename对您的命令无效,因为 $filename从未被定义。如果它被定义,它会产生各种错误;因为它没有定义并且扩展没有被引用,它只是从命令行中消失了,但是首先不把它放在那里会容易得多。
  • C 字符串可以使用反斜线换行符从一行到另一行继续,就像在您的示例代码中一样,但这不会在字符串中插入换行符。所以输入提供给 grep将是单行。我不认为那是你的意思。
  • 您必须引用此处的字符串; here-strings 的语法是 <<<后跟一个“词”;如果你不在它周围加上引号,你最终只会将第一个空格之前的部分视为输入。
  • 关于c++ - 在 ubuntu 中使用/bin/bash 运行 grep 时,popen 错误重定向意外,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32343591/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com