Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

system vs process command



  • void MainWindow::on_read_push_clicked()
    {

    system("cd /sys/bus/iio/devices/iio:device5; cat dwell_samples");

    QProcess process;
    process.start("cd /sys/bus/iio/devices/iio:device5; cat dwell_samples");
    process.waitForFinished(-1); // will wait forever until finished
    QString stdout = process.readAllStandardOutput();
    qDebug() << stdout;

    ui->lineEdit->setText(stdout);
    }

    // output of above system ("cd /sys/bus/iio/devices/iio:device5; cat dwell_samples");
    1024

    // the output of process.start("cd /sys/bus/iio/devices/iio:device5; cat dwell_samples");
    ""

    Selection_018.png
    Although I have checked both command as follows they worked fine:

    system("sudo devmem2 0x80000000");
    QProcess process;
    process.start("sudo devmem2 0x80000000");
    process.waitForFinished(-1); // will wait forever until finished
    QString stdout = process.readAllStandardOutput();
    qDebug() << stdout



  • @sierdzio , @Mijaz

    • In Linux/bash/sh, the (first) argument to the shell for executing a string is -c, not -C, and must be in lower-case.

    • In the second argument, the string of the command to execute, you must not embed literal double-quotes (the \"s shown above). Qt will end up protecting those, and you won't get a command which works. Since the whole point is of QProcess::start(program, arglist) overload is that it knows each argument is to be passed as a single argument to the program, you do not need or want to quote it yourself.

    • In this case you could make it easier on yourself by not passing a multi-statement command or needing to invoke the shell if you changed your command to the equivalent cat /sys/bus/iio/devices/iio:device5/dwell_samples.

    Of course, in the particular case of the example shown here, you don't want to use any OS/QProcess command at all. You are reading the output from a command which simply cats a file. That's a long way round from the much simpler and more efficient use of a QFile here in which you simply open & read the file's content...!


  • Moderators

    @Mijaz said in system vs process command:

    process.start("cd /sys/bus/iio/devices/iio:device5; cat dwell_samples");

    QProcess does not start any shell, it only attempts to start a process with given names and parameters. But you give here 2 separate calls and cram them together. Either run them separately or launch a shell like this:

    process.start("bash", QStringList { "-C", "\"cd /sys/bus/iio/devices/iio:device5; cat dwell_samples\"" });
    
    


  • @sierdzio
    I have executed your suggested command but there are error. I have added #include <QStringList>
    Selection_019.png


  • Moderators

    Add CONFIG += c++11 to your .pro file.

    Or build the string list manually:

    QStringList temp;
    temp.append("-C");
    temp.append("\"cd /sys/bus/iio/devices/iio:device5; cat dwell_samples\"");
    

    I have not checked the code on my side, it may have some errors still.



  • @sierdzio , @Mijaz

    • In Linux/bash/sh, the (first) argument to the shell for executing a string is -c, not -C, and must be in lower-case.

    • In the second argument, the string of the command to execute, you must not embed literal double-quotes (the \"s shown above). Qt will end up protecting those, and you won't get a command which works. Since the whole point is of QProcess::start(program, arglist) overload is that it knows each argument is to be passed as a single argument to the program, you do not need or want to quote it yourself.

    • In this case you could make it easier on yourself by not passing a multi-statement command or needing to invoke the shell if you changed your command to the equivalent cat /sys/bus/iio/devices/iio:device5/dwell_samples.

    Of course, in the particular case of the example shown here, you don't want to use any OS/QProcess command at all. You are reading the output from a command which simply cats a file. That's a long way round from the much simpler and more efficient use of a QFile here in which you simply open & read the file's content...!



  • @sierdzio
    I also tryed like this:
    Selection_020.png



  • @Mijaz
    Don't, you're all over the place. Your post may have crossed with mine above. Read what I have written and act on it.

    You can make your current command (if that's what you want) work via:

    process.start("/bin/bash", QStringList() << "-c", << "cd /sys/bus/iio/devices/iio:device5; cat dwell_samples");
    

    But as I said I wouldn't do that command that way.



  • @JonB
    thank you soo much.
    process.start("cat /sys/bus/iio/devices/iio:device5/dwell_samples");
    this worked greatly.



  • @Mijaz
    Yep, as you can see removing the need to cd makes it simpler, no shell.

    Though as I wrote above, if all you want to do is cat a file, you really don't want to spawn a sub-process and read its output, you can accomplish that directly from QFile without any QProcess:

    QFile f("/sys/bus/iio/devices/iio:device5/dwell_samples");
    if (f.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QByteArray ba = f.readAll();
        ui->lineEdit->setText(QString(ba));
        f.close();
    }
    

    Of course, that may not apply to other examples, e.g. the sudo devmem2 you mentioned.



  • @JonB
    process.start("cat /sys/bus/iio/devices/iio:device5/dwell_samples");

    I need to access kernel space, so id needs permission. How can I modify command to give permission (sudo su).

    The following command needs permission.
    I want to execute two process

    QProcess process1;
    process1.start("echo /sys/kernel/iio/devices/iio:device4/ 0x418 0x2 > direct_reg_access");
    process1.waitForFinished(-1); // will wait forever until finished
    QString stdout1 = process1.readAllStandardOutput();
    qDebug() << stdout1;

    QProcess process2;
    process2.start("cat /sys/kernel/iio/devices/iio:device4/ direct_reg_access");
    process2.waitForFinished(-1); // will wait forever until finished
    QString stdout2 = process2.readAllStandardOutput();
    qDebug() << stdout2;



  • @Mijaz
    This is rather a different question. Of the commands as you have written, #1 requires write permission to wherever the file direct_reg_access is (current directory). That's all, and I don't see anything special about that. It's not clear whether there is a space in the path in command #2, and that makes a difference as to what it's doing. I kind of suspect the commands as written do not do what you might be intending, I don't know. There's not much point in saying more till you clarify exactly what you are trying to do here. And if you expect people to understand you must either put spaces in or take them out correctly, else it's all guesswork for the reader.



  • Hi @JonB How are you?

    QProcess process1;
    process1.start("echo /sys/kernel/iio/devices/iio:device4/ 0x418 0x2 > direct_reg_access");
    process1.waitForFinished(-1); // will wait forever until finished
    QString stdout1 = process1.readAllStandardOutput();
    qDebug() << stdout1;

    Actually I want to display the output of different processes, so of course, I need a process with different names. However, right now I need to implement just one process. Do you have Idea how to give permission in-process command? As I mentioned to access direct_reg_access.


  • Lifetime Qt Champion

    Hi @Mijaz,

    isn't dwell_samples a file? So why bother with QProcess, bash and cat if you can simply open the file with QFile and read it?

    Regards



  • @aha_1980
    As you can see, I have already said this twice in responses above and even given the code.... To be fair, in his latest post the OP is no longer asking about Question #2, which is the one which can be done by simple QFile::read().



  • @Mijaz
    Here is your command, copied & pasted into triple-backticks here on this forum so that we can actually read it:

    process1.start("echo /sys/kernel/iio/devices/iio:device4/ 0x418 0x2 > direct_reg_access");
    

    So, this will put the characters

    /sys/kernel/iio/devices/iio:device4/ 0x418 0x2
    

    into a file named direct_reg_access.

    Now, as I have said before, this will create/overwrite that file in the current directory of whichever process it is run from. Why do you need any special permissions?

    Please log onto your Linux or whatever box, open a shell/terminal, and copy & paste the command you have written into it as the very first thing you do in the shell:

    echo /sys/kernel/iio/devices/iio:device4/ 0x418 0x2 > direct_reg_access
    

    Do you agree this works immediately, without any special permissions? Because your current directory is highly likely to be your home directory, and you have permission to create/write to files there. So, you don't need any special permissions, do you?

    Now, if it turns out that what you really mean is that you want to write to that file elsewhere, then you have to say so. I don't want to have to guess. Perhaps what you really mean is

    echo /sys/kernel/iio/devices/iio:device4/ 0x418 0x2 > /sys/kernel/iio/devices/iio:device4/direct_reg_access
    

    While we are here. Your question #2 , copied & pasted, says what you intend to do is:

    cat /sys/kernel/iio/devices/iio:device4/ direct_reg_access
    

    This will always error, because you cannot cat a directory. Try it yourself from a shell. I asked you before to look at your spacing and correct or tell us what you actually want to do.

    Finally, the whole process you have written is pointless. At the end of it, if you cat the direct_reg_access file you have created you will always get back precisely the string

    /sys/kernel/iio/devices/iio:device4/ 0x418 0x2
    

    so what is the whole point of the exercise?

    I will answer your question about permissions if you take the time to make clear what it is you actually want to do, where that file direct_reg_access is supposed to be, but not before....


Log in to reply