QT开发中文网

给我封装一个类,名称为CSSHPROCESS,类的作用为实现SSH与远程机器交互,在调用这个类创建实例时会传入三个参数:远程主机的用户名,主机地址,登录密码。创建实例时函数内部会使用QProcess将这几个参数作为QStringList传入连接远程机器的脚本中并运行连接,接下来的操作命令都是在使用ssh和expect与远程主机连接之后进行交互。要操作的的方法函数有: 1.复制文件,传入本地文件路径和远程机器文件路径,可以将远程机器文件复制到本地,也可以将本地文件发送到远程机器。其中要复制的...

头文件代码如下所示:

#ifndef CSSHPROCESS_H
#define CSSHPROCESS_H

#include <QObject>
#include <QStringList>
#include <QProcess>
#include <QList>

struct FileDetail {
    QString path;
    QString type; // d for directory, f for file
};

class CSSHProcess : public QObject
{
    Q_OBJECT
public:
    explicit CSSHProcess(QString username, QString host, QString password, QObject *parent = nullptr);
    ~CSSHProcess();

    void copyFiles(QList<FileDetail> files, QString remotePath); // Copy files from local to remote or vice versa
    void deleteFiles(QList<FileDetail> files); // Delete files on remote machine
    void backupFiles(QList<FileDetail> files, QString backupPath); // Backup files to specified location before modifying them
    void restoreFiles(QList<FileDetail> files); // Restore files from backup location
    QList<FileDetail> listDirectory(QString path); // List files in specified directory on remote machine
    void disconnect(); // Disconnect from remote machine and close terminal

private:
    QString m_username; // Remote machine username
    QString m_host; // Remote machine IP address or hostname
    QString m_password; // Remote machine login password
    QProcess *m_process; // Terminal process for interacting with remote machine
    QString m_tempDir; // Temporary directory for storing backup files
    bool m_isConnected; // Flag for whether the connection has been established

    void runCommand(QString command); // Run command on the remote machine using SSH and Expect scripts
    QStringList generateExpectCommands(QStringList commands); // Generate Expect commands based on the input SSH commands
    QString getFileNameFromPath(QString path); // Get the filename from a full file path
    void printTerminalOutput(); // Print the output of the terminal process to qDebug
};

#endif // CSSHPROCESS_H

源文件代码如下所示:

#include "csshprocess.h"
#include <QDir>
#include <QDebug>

CSSHProcess::CSSHProcess(QString username, QString host, QString password, QObject *parent)
    : QObject(parent), m_username(username), m_host(host), m_password(password), m_process(new QProcess(this)), m_isConnected(false)
{
    // Create temporary directory for backup files
    m_tempDir = QDir::tempPath() + "/sshbackup";
    QDir temp(m_tempDir);
    if (!temp.exists()) {
        temp.mkpath(".");
    }

    // Run command to connect to remote machine using SSH and Expect scripts
    QStringList sshCommands = {"ssh", m_username + "@" + m_host};
    QStringList expectCommands = generateExpectCommands(sshCommands);
    runCommand(expectCommands.join(" && "));

    // Set up signal-slot connection to print terminal output
    connect(m_process, &QProcess::readyReadStandardOutput, this, &CSSHProcess::printTerminalOutput);
    connect(m_process, &QProcess::readyReadStandardError, this, &CSSHProcess::printTerminalOutput);
}

CSSHProcess::~CSSHProcess()
{
    // Disconnect from remote machine and close terminal
    disconnect();
}

void CSSHProcess::copyFiles(QList<FileDetail> files, QString remotePath)
{
    QString scpCommand;
    QString sourcePath;
    QString destinationPath;

    // Loop through each file and add SCP command to the list of commands to run on the remote machine
    foreach (FileDetail file, files) {
        sourcePath = file.path;
        if (file.type == "d") {
            sourcePath += "/";
        }
        destinationPath = remotePath + "/" + getFileNameFromPath(file.path);
        scpCommand = "scp -r " + sourcePath + " " + m_username + "@" + m_host + ":" + destinationPath;
        runCommand(scpCommand);
    }
}

void CSSHProcess::deleteFiles(QList<FileDetail> files)
{
    QString rmCommand;

    // Loop through each file and add RM command to the list of commands to run on the remote machine
    foreach (FileDetail file, files) {
        rmCommand = "rm -r " + file.path;
        runCommand(rmCommand);
    }
}

void CSSHProcess::backupFiles(QList<FileDetail> files, QString backupPath)
{
    QString mkdirCommand;
    QString cpCommand;
    QString sourcePath;
    QString destinationPath;
    QDir tempDir(m_tempDir);

    // Create backup directory
    mkdirCommand = "mkdir -p " + backupPath;
    runCommand(mkdirCommand);

    // Loop through each file and copy it to the temporary backup directory
    foreach (FileDetail file, files) {
        sourcePath = file.path;
        if (file.type == "d") {
            sourcePath += "/";
        }
        destinationPath = m_tempDir + "/" + getFileNameFromPath(file.path);
        cpCommand = "cp -r " + sourcePath + " " + destinationPath;
        runCommand(cpCommand);
    }

    // Copy backup directory to specified location on remote machine
    scpCommand = "scp -r " + m_tempDir + "/* " + m_username + "@" + m_host + ":" + backupPath;
    runCommand(scpCommand);

    // Clean up temporary backup directory
    tempDir.removeRecursively();
}

void CSSHProcess::restoreFiles(QList<FileDetail> files)
{
    QString cpCommand;
    QString sourcePath;
    QString destinationPath;

    // Loop through each file and copy it from the backup directory to its original location on the remote machine
    foreach (FileDetail file, files) {
        sourcePath = getFileNameFromPath(file.path);
        if (file.type == "d") {
            destinationPath = file.path + "/";
        } else {
            destinationPath = file.path;
        }
        cpCommand = "cp -r " + m_tempDir + "/" + sourcePath + " " + destinationPath;
        runCommand(cpCommand);
    }
}

QList<FileDetail> CSSHProcess::listDirectory(QString path)
{
    QString lsCommand = "ls -l " + path;
    QStringList outputList;
    QStringList fileList;
    QList<FileDetail> fileDetails;

    // Run LS command on remote machine and capture output
    runCommand(lsCommand);

    // Parse output into list of file paths and types
    while (m_process->canReadLine()) {
        QString line = QString(m_process->readLine()).trimmed();
        outputList.append(line);
    }
    for (int i = 1; i < outputList.size(); i++) { // Skip first line as it's just the total file size
        QString line = outputList.at(i);
        QStringList parts = line.split(QRegExp("\\s+"), Qt::SkipEmptyParts);
        if (parts.size() >= 9) {
            QString filePath = parts.at(8);
            QString fileType = parts.at(0).left(1); // Get first character of permission string to determine file or directory
            FileDetail file = {filePath, fileType};
            fileDetails.append(file);
        }
    }

    return fileDetails;
}

void CSSHProcess::disconnect()
{
    if (m_isConnected) {
        runCommand("exit");
        m_process->waitForFinished();
        m_isConnected = false;
    }
}

void CSSHProcess::runCommand(QString command)
{
    // Write command to terminal process and wait for it to finish
    m_process->write(command.toUtf8() + "\r\n");
    m_process->waitForBytesWritten();
    m_process->waitForReadyRead(-1);
    m_isConnected = true;
}

QStringList CSSHProcess::generateExpectCommands(QStringList commands)
{
    QStringList expectCommands;

    // Generate command to connect to remote machine using SSH and Expect scripts
    expectCommands.append("spawn " + commands.at(0));
    expectCommands.append("expect \"assword:\"");
    expectCommands.append("send \"" + m_password + "\\r\"");
    expectCommands.append("interact");

    return expectCommands;
}

QString CSSHProcess::getFileNameFromPath(QString path)
{
    QFileInfo fileInfo(path);
    return fileInfo.fileName();
}

void CSSHProcess::printTerminalOutput()
{
    // Print terminal output to qDebug
    while (m_process->canReadLine()) {
        QString line = QString(m_process->readLine()).trimmed();
        qInfo() << line;
    }
}

脚本文件代码如下所示:

#!/usr/bin/expect -f

# Turn off output buffering
set timeout -1

# Connect to remote machine using SSH
spawn ssh $argv

# Expect password prompt and send password
expect "assword:"
send [lindex $argv 1]"\\r"

# Allow interaction with terminal session
interact

注意:上述代码仅供参考,可能需要根据具体情况进行修改和优化。

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:http://qt.0voice.com/?id=44

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?