How to verify Linux " system " call results ?
-
I am embarrassed to post this, but...
- how can I verify - using "system" call that file exist ?
- how can I redirect "system" call actual text / error returns to QT widget ?
I know how to read the pass / fail returns , no problem .
I need the actual valid text or error to show in widget.I know it can be done because of "stdio" redirecting , but totally forgot how.
text = " mkdir /tmp"; array = text.toLocal8Bit(); buffer = array.data(); result = system(buffer);
and it trows this error to console, I want to redirect it to widget.
mkdir: cannot create directory ‘/tmp’: File exists
Thanks
-
I am embarrassed to post this, but...
- how can I verify - using "system" call that file exist ?
- how can I redirect "system" call actual text / error returns to QT widget ?
I know how to read the pass / fail returns , no problem .
I need the actual valid text or error to show in widget.I know it can be done because of "stdio" redirecting , but totally forgot how.
text = " mkdir /tmp"; array = text.toLocal8Bit(); buffer = array.data(); result = system(buffer);
and it trows this error to console, I want to redirect it to widget.
mkdir: cannot create directory ‘/tmp’: File exists
Thanks
Hi @AnneRanch,
I am embarrassed to post this, but...
Nothing to be embarrassed about.
Before going any further, I must say: You really, really, should consider using something like QProcess for this - it will save you a huge amount of re-invention effort! :D
That said, if you must use old Standard C library functions...
- how can I verify - using "system" call that file exist ?
There are so many ways. If you must use
system()
, then maybe usestat
like:auto result = system("stat /tmp > /dev/null 2>&1");
But it would be better to use the (Standard C)
fstat()
function directly, rather than going throughsystem()
, and much, much, much better to use QFile::exits() instead.- how can I redirect "system" call actual text / error returns to QT widget ?
You can't from outside the
system()
call - you need to do the redirection inside the executed command itself, eg:system("mkdir /tmp > my-comands-stdout.txt 2> my-commands-stderr.txt");
Of course then you need to clean up the temporary files afterwards. And if performance matters (unlikely with
mkdir
) then you'd want tomkfifo()
for the output files.system()
is essentially a convenience wrapper aroundpopen()
orexecl()
, and the above is effectively working around the shortcutssystem()
provides, so, you would be much better off switching to usingpopen()
instead ofsystem()
.And again, you would be much, much, much better of just using QProcess instead!
mkdir: cannot create directory ‘/tmp’: File exists
Just a side note, you might want to use
mkdir
's-p
option. But in this case, I would super-strongly recommend QDir::mkpath() instead.Cheers.
-
Hi @AnneRanch,
I am embarrassed to post this, but...
Nothing to be embarrassed about.
Before going any further, I must say: You really, really, should consider using something like QProcess for this - it will save you a huge amount of re-invention effort! :D
That said, if you must use old Standard C library functions...
- how can I verify - using "system" call that file exist ?
There are so many ways. If you must use
system()
, then maybe usestat
like:auto result = system("stat /tmp > /dev/null 2>&1");
But it would be better to use the (Standard C)
fstat()
function directly, rather than going throughsystem()
, and much, much, much better to use QFile::exits() instead.- how can I redirect "system" call actual text / error returns to QT widget ?
You can't from outside the
system()
call - you need to do the redirection inside the executed command itself, eg:system("mkdir /tmp > my-comands-stdout.txt 2> my-commands-stderr.txt");
Of course then you need to clean up the temporary files afterwards. And if performance matters (unlikely with
mkdir
) then you'd want tomkfifo()
for the output files.system()
is essentially a convenience wrapper aroundpopen()
orexecl()
, and the above is effectively working around the shortcutssystem()
provides, so, you would be much better off switching to usingpopen()
instead ofsystem()
.And again, you would be much, much, much better of just using QProcess instead!
mkdir: cannot create directory ‘/tmp’: File exists
Just a side note, you might want to use
mkdir
's-p
option. But in this case, I would super-strongly recommend QDir::mkpath() instead.Cheers.
@Paul-Colby You are "the man " Nice , very much needed to continue my project.
BTW
I have been using QProcess and decided to switch / try "system" - since they are both based on same.
My concerns about QProcess - when I started I have been told that I really cannot interact with QProcess.
I have been experimenting with "ready to read" time and "timeout" and found that when my command actually fails to execute my code fails "ready to read" and goes into "timeout" immediately.
So my next step was to identify such false timeout failure as the command failure...It seems that "system" may do that better, after I digest you last post.
-
@Paul-Colby You are "the man " Nice , very much needed to continue my project.
BTW
I have been using QProcess and decided to switch / try "system" - since they are both based on same.
My concerns about QProcess - when I started I have been told that I really cannot interact with QProcess.
I have been experimenting with "ready to read" time and "timeout" and found that when my command actually fails to execute my code fails "ready to read" and goes into "timeout" immediately.
So my next step was to identify such false timeout failure as the command failure...It seems that "system" may do that better, after I digest you last post.
@AnneRanch
With respect, QProcess is the better approach to access system shell commands, albeit more complicated.
system() (POSIX call) stalls the running program until the child terminates.
As long as you are aware of that, and can accept the consequences.
man 3 system explains it...It forks, does an execl(), and then waits for the pid to terminate before the parent continues.
As @Paul-Colby mentions, there are calls that check for file exists, so the above comments may not be relevant, but it is important to understand that system() stalls the parent.
-
As said before. You can do much more interacting with
QProcess
than withsystem()
. The latter simply runs/bin/sh -c "your command with any arguments"
and waits for it to finish. There is nothing it does which cannot be done viaQProcess
. Effectively thestatic
functionQProcess::execute("/bin/sh", { "-c", "your command with any arguments"
})' does just the same thing.Both of these suffer because any output from the command is written to stdout/stderr, and you cannot access those without doing redirection from the calling program (which we could do from the Qt application, but it's an effort we don't need). So for example you will not see any error output which is what you are asking for.
However, with
QProcess
the following does allow to access any output:// next 3 lines do the same as `system("mkdir /tmp")` QProcess p; p.start("/bin/sh", { "-c", "mkdir /tmp" }); qDebug() << p.waitForFinished(); // next 2 lines read any output, which cannot be done so easily from `system()` qDebug() << p.readAllStandardOutput(); qDebug() << p.readAllStandardError(); // or above two lines can be replaced by `qDebug() << p.readAll()` if you don't want to see stdout/stderr separately
I imagine
p.readAllStandardError();
will report something like/tmp: Directory already exists
here.If you always use this
QProcess
pattern and never usesystem()
in a Qt application you will always be able to access a command's output, plus write to its input if wanted, with no disadvantages. -
As said before. You can do much more interacting with
QProcess
than withsystem()
. The latter simply runs/bin/sh -c "your command with any arguments"
and waits for it to finish. There is nothing it does which cannot be done viaQProcess
. Effectively thestatic
functionQProcess::execute("/bin/sh", { "-c", "your command with any arguments"
})' does just the same thing.Both of these suffer because any output from the command is written to stdout/stderr, and you cannot access those without doing redirection from the calling program (which we could do from the Qt application, but it's an effort we don't need). So for example you will not see any error output which is what you are asking for.
However, with
QProcess
the following does allow to access any output:// next 3 lines do the same as `system("mkdir /tmp")` QProcess p; p.start("/bin/sh", { "-c", "mkdir /tmp" }); qDebug() << p.waitForFinished(); // next 2 lines read any output, which cannot be done so easily from `system()` qDebug() << p.readAllStandardOutput(); qDebug() << p.readAllStandardError(); // or above two lines can be replaced by `qDebug() << p.readAll()` if you don't want to see stdout/stderr separately
I imagine
p.readAllStandardError();
will report something like/tmp: Directory already exists
here.If you always use this
QProcess
pattern and never usesystem()
in a Qt application you will always be able to access a command's output, plus write to its input if wanted, with no disadvantages.@JonB
Thanks everybody for all the comments. Appreciate that very much.As of right now I actually have basic issue with just the "command".
I am getting confusing and conflicting results.
"echo q | sudo -S -k unlink /dev/rfcomm0 "
sh: 1: ��x3��t: not found
sh: 1: ��tn�S���v~��ty��tL��tG��tB��t=�P�D�H��[]A�: not found
"echo q | sudo -S -k unlink /dev/rfcomm0 FAILURE not un linked "Since /dev/rfcomm0 does not yet exists the above is OK, I have no idea where the gobberish comes from.
"echo q | sudo -S -k ln -s -v /dev/ttyUSB /dev/rfcomm0 | tee temp_link.txt | tee temp_link_copy.txt"
[sudo] password for nov25-1: ln: failed to create symbolic link '/dev/rfcomm0': File existsNow this is wrong - contradicts "unlink" command.
I need to find the reason why."echo q | sudo -S -k ln -s -v /dev/ttyUSB /dev/rfcomm0 | tee temp_link.txt | tee temp_link_copy.txt SUCCESS linked "
I am actually unable to determine , from the command itself , where the "tee" creates the file(s).
I did try
text += " | tee /home/temp_link.txt ;
but it requires another authorization and I just do not know how
to add another "sudo" to the already convoluted
command.I would actually like to have the temp file in main .pro folder.
That is my main task right now,
I will decide between QProcess or system after I get
the commands to behave.PS
I do not get why everybody is always concern with "stalling the main process" -
it does not matter if the main process is blocked - it cannot
function until the "child process" is finished anyway.
It would work just fine, for my application, if I process the "command"
in parent and just skip creating the "child". -
@JonB
Thanks everybody for all the comments. Appreciate that very much.As of right now I actually have basic issue with just the "command".
I am getting confusing and conflicting results.
"echo q | sudo -S -k unlink /dev/rfcomm0 "
sh: 1: ��x3��t: not found
sh: 1: ��tn�S���v~��ty��tL��tG��tB��t=�P�D�H��[]A�: not found
"echo q | sudo -S -k unlink /dev/rfcomm0 FAILURE not un linked "Since /dev/rfcomm0 does not yet exists the above is OK, I have no idea where the gobberish comes from.
"echo q | sudo -S -k ln -s -v /dev/ttyUSB /dev/rfcomm0 | tee temp_link.txt | tee temp_link_copy.txt"
[sudo] password for nov25-1: ln: failed to create symbolic link '/dev/rfcomm0': File existsNow this is wrong - contradicts "unlink" command.
I need to find the reason why."echo q | sudo -S -k ln -s -v /dev/ttyUSB /dev/rfcomm0 | tee temp_link.txt | tee temp_link_copy.txt SUCCESS linked "
I am actually unable to determine , from the command itself , where the "tee" creates the file(s).
I did try
text += " | tee /home/temp_link.txt ;
but it requires another authorization and I just do not know how
to add another "sudo" to the already convoluted
command.I would actually like to have the temp file in main .pro folder.
That is my main task right now,
I will decide between QProcess or system after I get
the commands to behave.PS
I do not get why everybody is always concern with "stalling the main process" -
it does not matter if the main process is blocked - it cannot
function until the "child process" is finished anyway.
It would work just fine, for my application, if I process the "command"
in parent and just skip creating the "child".@AnneRanch said in How to verify Linux " system " call results ?:
PS
I do not get why everybody is always concern with "stalling the main process" -
it does not matter if the main process is blocked - it cannot
function until the "child process" is finished anyway.because the essense of event driven programming is an event loop that needs to be continually running. You're still thinking in procedural progamming terms, not event driven terms. It's doing a lot of "stuff" behind the scenes that you don't see...that's one of the reasons we use a framework instead of doing everything brute force. it does a lot of the housekeeping for you behind the scenes.
-
Here is an update.
Went back to project backup copy and got rid of the gibberish.The result of the "ln" ( '/dev/rfcomm0' -> '/dev/ttyUSB0' ) is now in the temporary file
which resides in my main .pro folder .
Do not like it there , but...I like to redirect good "ln" result into QString using stdio - if possible-
,and error too.
I am working on that but could still use some assistance to add that to the current command."TASK unlink "
" echo q | sudo -S -k unlink /dev/rfcomm0 "
[sudo] password for nov25-1: " echo q | sudo -S -k unlink /dev/rfcomm0 SUCCESS un linked "
" Result system 0"
"TASK link - add tee "
" echo q | sudo -S -k ln -s -v /dev/ttyUSB0 /dev/rfcomm0 | tee temporary_link_file.txt"
[sudo] password for nov25-1: '/dev/rfcomm0' -> '/dev/ttyUSB0'
" echo q | sudo -S -k ln -s -v /dev/ttyUSB0 /dev/rfcomm0 | tee temporary_link_file.txt SUCCESS linked "
" Result system 0"