How to Execute SCP command to transfer files to a target machine
-
#include "transfer.h"
#include "ui_transfer.h"
#include <sstream>
#include <QProcess>
#include <iostream>
#include <QDebug>
#include <QFileDialog>
#include <QtWidgets>Transfer::Transfer(QWidget *parent) :
QDialog(parent),
ui(new Ui::Transfer)
{
ui->setupUi(this);
}Transfer::~Transfer()
{
delete ui;
}void Transfer::on_pushButton_Go_clicked()
{ proc = new QProcess() ;
QString command = "scp" ;
QString ip = ui->lineEdit_IP_Address->text() ;
QString username = ui->lineEdit_SSH_username->text() ;
QString dest_path = ui->lineEdit_TransferToTarget_DestinationFolder->text() ;
QString source_path = ui->lineEdit_TransferToTarget_SourcePath->text() ;
std::stringstream s ;
s << username.toStdString() << "@" << ip.toStdString() << ":" << dest_path.toStdString();
std::cout << s.str() << std::endl ;
QStringList params ;
params.append(source_path) ;
params.append(QString::fromStdString(s.str())) ;
qDebug() << params ;
// params.append("/home/span51/Desktop/readme.txt");
// params.append("spanidea@192.168.1.26:/home/spanidea/test" );
connect(this, SIGNAL(readyReadStandardError()), this, SLOT(readOutput()));
connect(this, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));
proc->startDetached(command,params) ;/* QString StdOut = proc.readAllStandardOutput(); //Reads standard output
QString StdError = proc.readAllStandardError(); //Reads standard error
std::cout<<"\n Printing the standard output..........\n";
std::cout<<endl<<StdOut.toStdString();
std::cout<<"\n Printing the standard error..........\n";
std::cout<<endl<<StdError.toStdString();
*/
}void Transfer::on_pushButton_choosefile_transferTotarget_clicked()
{
QString filepath = QFileDialog::getOpenFileName(this, tr("Transfer file"), "/home","Config_Files(*.c)") ;
ui->lineEdit_TransferToTarget_SourcePath->setText(filepath);
}void Transfer::on_pushButton_Std_output_clear_clicked()
{
ui->textEdit_Standard_output->clear() ;
}void Transfer::on_checkBox_Show_Password_clicked(bool checked)
{
if (checked)
ui->lineEdit_SSH_password->setEchoMode(QLineEdit::Normal);
else
ui->lineEdit_SSH_password->setEchoMode(QLineEdit::Password);
}void Transfer::readOutput()
{
QString StdOut = proc->readAllStandardOutput(); //Reads standard output
QString StdError = proc->readAllStandardError(); // Reads standard error
ui->textEdit_Standard_output->setText(StdOut);
ui->textEdit_Standard_output->setText(StdError);
}its building successfully, nothing printing on textedit can find some thing into this.
while debugging i saw slot function is not getting called.@moyin said in How to Execute SCP command to transfer files to a target machine:
connect(this, SIGNAL(readyReadStandardError()), this, SLOT(readOutput()));
connect(this, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));You should read more carefully. You need to connect the signals from the PROCESS not from this!
connect(process, SIGNAL(readyReadStandardError(), this, SLOT(readOutput())); connect(process, SIGNAL(readyReadStandardOutput(), this, SLOT(readOutput()));
You should also connect a slot to http://doc.qt.io/qt-5/qprocess.html#errorOccurred and print errors you get to be able to find issues faster.
-
@moyin said in How to Execute SCP command to transfer files to a target machine:
connect(this, SIGNAL(readyReadStandardError()), this, SLOT(readOutput()));
connect(this, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));You should read more carefully. You need to connect the signals from the PROCESS not from this!
connect(process, SIGNAL(readyReadStandardError(), this, SLOT(readOutput())); connect(process, SIGNAL(readyReadStandardOutput(), this, SLOT(readOutput()));
You should also connect a slot to http://doc.qt.io/qt-5/qprocess.html#errorOccurred and print errors you get to be able to find issues faster.
@jsulm i tried this also,
connect(proc, SIGNAL(readyReadStandardError()), this, SLOT(readOutput()));
connect(proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));
proc->startDetached(command,params) ;but same result, nothing will be printing on textedit.
-
@jsulm i tried this also,
connect(proc, SIGNAL(readyReadStandardError()), this, SLOT(readOutput()));
connect(proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));
proc->startDetached(command,params) ;but same result, nothing will be printing on textedit.
@moyin Connect a slot to http://doc.qt.io/qt-5/qprocess.html#errorOccurred and see whether you get any error.
-
@moyin said in How to Execute SCP command to transfer files to a target machine:
ui->textEdit_Standard_output->setText(StdOut);
ui->textEdit_Standard_output->setText(StdError);If StdError is empty, then you are effectively overwriting your StdOut. Consider doing this instead:
ui->textEdit_Standard_output->setText(ui->textEdit_Standard_output->text() + StdOut + StdError);
And please use code tags when writing on this forum, it makes reading the code much easier.
-
@moyin Connect a slot to http://doc.qt.io/qt-5/qprocess.html#errorOccurred and see whether you get any error.
@jsulm i tried this, it does't works.
connect(&proc, SIGNAL(readyReadStandardError()), this, SLOT(readOutput())); connect(&proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput())); connect(&proc, SIGNAL(errorOccurred()), this, SLOT(readOutput())); proc.startDetached(command,params) ;
And did changes in readoutput() also,
ui->textEdit_Standard_output->setText(ui->textEdit_Standard_output->toPlainText() + StdOut + StdError);
-
@jsulm i tried this, it does't works.
connect(&proc, SIGNAL(readyReadStandardError()), this, SLOT(readOutput())); connect(&proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput())); connect(&proc, SIGNAL(errorOccurred()), this, SLOT(readOutput())); proc.startDetached(command,params) ;
And did changes in readoutput() also,
ui->textEdit_Standard_output->setText(ui->textEdit_Standard_output->toPlainText() + StdOut + StdError);
@jsulm @sierdzio i'm sharing my .h and .cpp files as well it may help u to understand my problem.
transfer.h
#ifndef TRANSFER_H #define TRANSFER_H #include <QDialog> #include <QProcess> namespace Ui { class Transfer; } class Transfer : public QDialog { Q_OBJECT public: explicit Transfer(QWidget *parent = 0); ~Transfer(); private slots: void on_pushButton_Go_clicked(); void on_pushButton_choosefile_transferTotarget_clicked(); void on_pushButton_Std_output_clear_clicked(); void on_checkBox_Show_Password_clicked(bool checked); void readOutput() ; private: Ui::Transfer *ui; QProcess proc ; /* signals: void readyReadStandardOutput() ; void readyReadStandardError() ; */ }; #endif // TRANSFER_H
transfer.cpp
#include "transfer.h" #include "ui_transfer.h" #include <sstream> #include <QProcess> #include <iostream> #include <QDebug> #include <QFileDialog> #include <QtWidgets> Transfer::Transfer(QWidget *parent) : QDialog(parent), ui(new Ui::Transfer) { ui->setupUi(this); } Transfer::~Transfer() { delete ui; } void Transfer::on_pushButton_Go_clicked() { //proc = new QProcess() ; QString command = "scp" ; QString ip = ui->lineEdit_IP_Address->text() ; QString username = ui->lineEdit_SSH_username->text() ; QString dest_path = ui->lineEdit_TransferToTarget_DestinationFolder->text() ; QString source_path = ui->lineEdit_TransferToTarget_SourcePath->text() ; std::stringstream s ; s << username.toStdString() << "@" << ip.toStdString() << ":" << dest_path.toStdString(); std::cout << s.str() << std::endl ; QStringList params ; params.append(source_path) ; params.append(QString::fromStdString(s.str())) ; qDebug() << params ; // params.append("/home/span51/Desktop/readme.txt"); // params.append("spanidea@192.168.1.26:/home/spanidea/test" ); connect(&proc, SIGNAL(readyReadStandardError()), this, SLOT(readOutput())); connect(&proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput())); connect(&proc, SIGNAL(errorOccurred()), this, SLOT(readOutput())); proc.startDetached(command,params) ; /* QString StdOut = proc.readAllStandardOutput(); //Reads standard output QString StdError = proc.readAllStandardError(); //Reads standard error std::cout<<"\n Printing the standard output..........\n"; std::cout<<endl<<StdOut.toStdString(); std::cout<<"\n Printing the standard error..........\n"; std::cout<<endl<<StdError.toStdString(); */ } void Transfer::on_pushButton_choosefile_transferTotarget_clicked() { QString filepath = QFileDialog::getOpenFileName(this, tr("Transfer file"), "/home","Config_Files(*.c)") ; ui->lineEdit_TransferToTarget_SourcePath->setText(filepath); } void Transfer::on_pushButton_Std_output_clear_clicked() { ui->textEdit_Standard_output->clear() ; } void Transfer::on_checkBox_Show_Password_clicked(bool checked) { if (checked) ui->lineEdit_SSH_password->setEchoMode(QLineEdit::Normal); else ui->lineEdit_SSH_password->setEchoMode(QLineEdit::Password); } void Transfer::readOutput() { QString StdOut = proc.readAllStandardOutput(); //Reads standard output QString StdError = proc.readAllStandardError(); // Reads standard error // ui->textEdit_Standard_output->setText(StdOut); // ui->textEdit_Standard_output->setText(StdError); ui->textEdit_Standard_output->setText(ui->textEdit_Standard_output->toPlainText() + StdOut + StdError); }
-
@jsulm i tried this, it does't works.
connect(&proc, SIGNAL(readyReadStandardError()), this, SLOT(readOutput())); connect(&proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput())); connect(&proc, SIGNAL(errorOccurred()), this, SLOT(readOutput())); proc.startDetached(command,params) ;
And did changes in readoutput() also,
ui->textEdit_Standard_output->setText(ui->textEdit_Standard_output->toPlainText() + StdOut + StdError);
@moyin You again did not read documentation, right? http://doc.qt.io/qt-5/qprocess.html#errorOccurred
Else you would see that errorOccurred() has a parameter.
This connect cannot succeed (you should see a warning at runtime):connect(&proc, SIGNAL(errorOccurred()), this, SLOT(readOutput()));
You need to use another slot with
QProcess::ProcessError error
parameter and print out its value. -
@moyin You again did not read documentation, right? http://doc.qt.io/qt-5/qprocess.html#errorOccurred
Else you would see that errorOccurred() has a parameter.
This connect cannot succeed (you should see a warning at runtime):connect(&proc, SIGNAL(errorOccurred()), this, SLOT(readOutput()));
You need to use another slot with
QProcess::ProcessError error
parameter and print out its value. -
@jsulm i can transfer file successfully to the target machine without errors. but wanted to redirect logs whatever (stdout,stderr, etc..,) to textedit. than
why should go for QProcess::ProcessError.@moyin Then check whether these connects actually were successful:
qDebug() << connect(&proc, SIGNAL(readyReadStandardError()), this, SLOT(readOutput())); qDebug() << connect(&proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));
Place a qDebug() in your readOutput() to print something out to see whether the slot is actually called.
-
@moyin Then check whether these connects actually were successful:
qDebug() << connect(&proc, SIGNAL(readyReadStandardError()), this, SLOT(readOutput())); qDebug() << connect(&proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));
Place a qDebug() in your readOutput() to print something out to see whether the slot is actually called.
-
@jsulm i mentioned u already that, while debug if i put break point at or in readoutput() that will stop at break point so it means slot is not getting called.
@moyin said in How to Execute SCP command to transfer files to a target machine:
while debug if i put break point at or in readoutput() that will stop at break point so it means slot is not getting called
sorry, I'm confused: if it stops at the break point inside readOutput() then it means that it is actually called.
Try this:
void Transfer::readOutput() { QString StdOut = proc.readAllStandardOutput(); //Reads standard output QString StdError = proc.readAllStandardError(); // Reads standard error qDebug() << StdOut; qDebug() << StdError; // ui->textEdit_Standard_output->setText(StdOut); // ui->textEdit_Standard_output->setText(StdError); ui->textEdit_Standard_output->setText(ui->textEdit_Standard_output->toPlainText() + StdOut + StdError); }
Do you see anything in Application Output?
-
@jsulm i mentioned u already that, while debug if i put break point at or in readoutput() that will stop at break point so it means slot is not getting called.
-
@moyin said in How to Execute SCP command to transfer files to a target machine:
proc.startDetached(command,params) ;
Hm, startDetached() is a static call, so attaching any signals to it won't work, right? Shouldn't start() be used here instead? Just a thought, I have not analysed this code in-depth.
-
@moyin Then check whether these connects actually were successful:
qDebug() << connect(&proc, SIGNAL(readyReadStandardError()), this, SLOT(readOutput())); qDebug() << connect(&proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));
Place a qDebug() in your readOutput() to print something out to see whether the slot is actually called.
@jsulm its printing true for both
qDebug() << connect(&proc, SIGNAL(readyReadStandardError()), this, SLOT(readOutput())); qDebug() << connect(&proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));``` qDebug() in readOutput() is not printing any thing.
-
@jsulm its printing true for both
qDebug() << connect(&proc, SIGNAL(readyReadStandardError()), this, SLOT(readOutput())); qDebug() << connect(&proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));``` qDebug() in readOutput() is not printing any thing.
@moyin This is your problem:
proc.startDetached(command,params) ;
startDetached() is a static method! So you start your process, but it is not managed by the proc instance! Use start() instead:
proc.start(command, params);
-
@moyin This is your problem:
proc.startDetached(command,params) ;
startDetached() is a static method! So you start your process, but it is not managed by the proc instance! Use start() instead:
proc.start(command, params);