简体   繁体   English

无法在C ++程序中获取Linux'dd'命令的输出

[英]Having trouble getting the output of Linux 'dd' command in C++ program

I'm trying to use the sudo dd if=/dev/sda ibs=1 count=64 skip=446 command to get the partition table information from the master boot record in order to parse it I'm basically trying to read the output to a string in order to parse it, but all I'm getting is the following: ! 我正在尝试使用sudo dd if=/dev/sda ibs=1 count=64 skip=446命令从主引导记录中获取分区表信息以对其进行解析,我基本上是在尝试读取输出在顺序的一串解析它,但所有我得到如下: ! . What I'm expecting is: 我期望的是:

80 01 01 00 83 FE 3F 01 3F 00 00 00 43 7D 00 00 00 00 01 02 83 FE 3F 0D 82 7D 00 00 0C F1 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

My current code looks like this, and is just taken from here: How to execute a command and get output of command within C++ using POSIX? 我当前的代码是这样的,并且仅从这里获取: 如何使用POSIX在C ++中执行命令并获取命令输出?

#include <iostream>
#include <stdexcept>
#include <stdio.h>
#include <string>

using namespace std;

string exec(const char* cmd) {
    char buffer[128];
    string result = "";
    FILE* pipe = popen(cmd, "r");
    if (!pipe) throw std::runtime_error("popen() failed!");
    try {
        while (!feof(pipe)) {
            if (fgets(buffer, 128, pipe) != NULL)
                result += buffer;
        }
    } catch (...) {
        pclose(pipe);
        throw;
    }
    pclose(pipe);
    return result;
}

int main() {

    string s = exec("sudo dd if=/dev/sda ibs=1 count=64 skip=446");
    cout << s;

}

Obviously I'm doing something wrong, but I can't figure out the problem. 显然我做错了,但我无法弄清楚问题所在。 How do I get the proper output into my string? 如何将正确的输出输入字符串?

while (!feof(pipe)) {

This is your first bug . 这是您的第一个错误

result += buffer;

This is your second bug. 这是您的第二个错误。 buffer is a char array, which decays to a char * in this context. buffer是一个char数组,在这种情况下会衰减为char * As you know, a char * in a string context gets typically interpreted as a C-style string that's terminated by a ' \\0 ' byte. 如您所知,字符串上下文中的char *通常被解释为以' \\0 '字节终止的C样式字符串。

You might've noticed that you expect to get a bunch of 00 bytes read. 您可能已经注意到,您希望读取一堆00字节的数据。 Well, after the char array gets decayed to a char * , everything up to the first 00 byte is going to get appended to your result , rather than the 128 bytes, exactly. 好吧,在将char数组分解为char * ,直到前00个字节的所有内容都将附加到您的result ,而不是确切地附加到128个字节中。 And if there were no 00 bytes in those 128 bytes, you'll probably end up getting some random garbage, as an extra bonus, with a small possibility of a crash. 而且如果这128个字节中没有00字节,您可能最终会得到一些随机垃圾,这是额外的好处,并且崩溃的可能性很小。

if (fgets(buffer, 128, pipe) != NULL)

This is your third bug. 这是您的第三个错误。 If the read data happens to include a 0A byte, an '\\n' character, this is not going to read 128 bytes. 如果读取的数据恰好包含一个0A字节和一个'\\n'字符,则不会读取128个字节。

cout << s;

This is your fourth bug. 这是您的第四个错误。 Since the data will (after all the other bugs are fixed) presumably contain binary stuff, your terminal is inlikely to have much success displaying various bytes, especially bytes 00 through 1F . 由于数据(在修复了所有其他错误之后)可能包含二进制内容,因此您的终端不太可能成功显示各种字节,尤其是001F字节。

To fix your code you will need to: 要修复您的代码,您将需要:

  1. Correctly handle the end-of-file condition. 正确处理文件结束条件。

  2. Correctly read binary data. 正确读取二进制数据。 fgets() , et al, are completely unsuitable for the task. fgets()等完全不适合该任务。 If you insist on using C file structures, your only reasonable option is to use fread() . 如果您坚持使用C文件结构,则唯一合理的选择是使用fread()

  3. Correctly assemble a std::string from a blob of binary data. 从二进制数据的blob中正确地组装一个std::string Merely appending a char buffer to it, crossing your fingers, and hoping for the best, will not work. 仅在其上附加一个char缓冲区,用手指交叉并希望达到最佳效果,将无法正常工作。 You will most likely need to use the two-argument std::string constructor, that takes a beginning and an ending iterator value as parameters. 您很可能需要使用两个参数的std::string构造函数,该构造函数以开始和结束的迭代器值作为参数。

  4. Display binary data correctly, instead of just dumping the entire blob to std::cout , just like that. 正确显示二进制数据,而不是像那样将整个Blob转储到std::cout The most common approach is a std::hex manipulator, and diligent up-conversion of each char to an int , as an unsigned value . 最常见的方法是std::hex操纵器,并将每个char勤奋地向上转换为int作为无符号值)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM