Qt run shell on terminal - linux

I need to run shell from Qt application in mac
QString strProcess = "/bin/bash ";
strProcess += (QDir::currentPath() + "/../../../apk_build.sh");
strProcess += " -a " + ui->textEdit_apk->toPlainText();
strProcess += " -o " + ui->textEdit_out->toPlainText();
strProcess += " -c " + ui->textEdit_channel->toPlainText();
QProcess process;
process.execute(strProcess);
here some problem.
problem 1: it can not show content info in terminal , I need to see running info.
problem 2: it can not find apktool: command not found. apktool can be find if I execute command in terminal without Qt Application(apktool path: /usr/bin/apktool).

Problem1
If you want just to save output of the process then just set standard output of process.
void QProcess::setStandardOutputFile ( const QString & fileName, OpenMode mode = Truncate )
If you want to get output in real time then you have to handle your process as standard sequential I/O device by calling read (), readLine () functions.
Problem 2
You have to load environment variable of you user. Try to:
source /etc/profile

Related

sshfs with pexpect reported no error but failed to mount (Python 3)

I ask for help!
command = "sshfs " + username + "#" + host + ":" + hostdirectory \
+ " " + mountpoint + " -o nonempty "
sshfs = pexpect.spawn(command)
sshfs.expect(username + "#" + host + "'s password: ")
time.sleep(1)
sshfs.sendline(password)
time.sleep(10)
sshfs.expect(pexpect.EOF)
Runs without error, but /home/user/Mnt/ is empty. I run the code on Linux Mint 20.1.
sshfs should have been killed by SIGHUP prematurely.
Try ignoring SIGHUP like this:
command = "sshfs " + ...
pexpect.spawn('bash', args=['-c', "trap '' HUP; " + command])
...
Same effect for ignoring SIGHUP signal by keyword argument ignore_sighup=True. It's keeping sshfs running in background.
sshfs = pexpect.spawn(command, ignore_sighup=True)
See doc

Periodic STDIN for a bash command through Python 3

I have a simple C++ program:
#include<bits/stdc++.h>
using namespace std;
int main() {
while(1) {
string s;
cout << "Enter command: ";
cin >> s;
if (s == "end") {
break;
}
cout << "Sent command: " << s << "\n";
}
return 0;
}
I want to read a set of commands from another file, say cmd.txt as below:
start
go 10
r 20
go 10
stop
end
and so on. But it should be periodic, i.e.,
read start; wait for 1 minute
read go 10; wait for 1 minute... and so on.
To solve this, I thought I can use subprocess from Python 3 and then issue the bash command with stdin being read from the file and supplied periodically. But, the command seems to be blocking in the first place itself.
Here is the script that I have tried so far:
import subprocess
patterns = ['rectangle.txt', 'hexagon.txt']
subprocess.run(["g++", "reads.cpp", "-o", "reads"], shell=True)
for ptr in patterns:
print('Testing commands from ', ptr)
subprocess.run(["./reads"], shell=True)
commands = open(ptr, 'r').readlines()
for cmd in commands:
print(cmd, end='')
So, how can I achieve this? Or should I use only Bash for this?

Scons PreAction Command is printed but apparently not executed

I'm building a large project with SCONS, for reasons out of this topic (large story) I need to pass the object files options in the final linkage command inside a file.
Eg:
gcc -o program.elf #objects_file.txt -T linker_file.ld
This command works since I've tested it manually. But now I need to run it embedded in the Project build files. My first approach/idea has been to collect all the options into a file in the following way:
dbg_exe = own_env.Program('../' + target_path, components)
own_env.AddPreAction(dbg_exe, 'echo \'$SOURCES\' > objects_file.txt')
note: the $sources contains all the object files I need.
As I expected the command seems to be executed , I see the command printed in the terminal but for some reason it has not been executed since I don't find the objects_file.txt anywhere.
It's curious that if I copy & paste the printed lines in the same terminal the command execution is successful so I suppose the syntax constructed is correct.
I tried also a shorter test code:
own_env.AddPreAction(dbg_exe, 'ls -l > salida_ls.txt')
... and another surprise , this time I get syntax error in the console:
scons: done reading SConscript files.
scons: Building targets ...
ls -l > salida_ls.txt
ls: cannot access '>': No such file or directory
ls: cannot access 'salida_ls.txt': No such file or directory
a simple 'ls -l' works fine.
Any idea why this kind of bash commands don't work as expected? Is the > redirection symbol affecting the SCONS?
Some maybe useful information:
OS Windows10
Terminal mingw32
SCons v2.3.1
After searching I've found out that this is something related with the redefinition of the SPAWN construction variable:
def w32api_spawn(sh, escape, cmd, args, e_env):
print "CMD value"
print sh
print escape
print cmd
print args
print e_env
print " ********************************** "
if cmd == "SHELL":
return SCons.Platform.win32.spawn(sh,escape,args[1], args[1:],e_env)
cmdline = cmd + ' ' + string.join(args[1:], ' ')
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
proc = subprocess.Popen(
cmdline,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
startupinfo=startupinfo,
shell = False,
env = None
)
data, err = proc.communicate()
print data
rv = proc.wait()
if rv:
print "====="
print err
print "====="
return rv
Looks like you'll need to swap back to the default SPAWN for that Program().
Add this to the top of that SConscript
from SCons.Platform.win32 import spawn
Then replace the logic you pasted above with:
dbg_exe = own_env.Program('../' + target_path, components, SPAWN=spawn)
own_env.AddPreAction(dbg_exe, 'echo \'$SOURCES\' > objects_file.txt')
This assumes that you're only building on win32. If that's not true you'll need to conditionally add the SPAWN to your Program() above only when you're on win32.
Finally I found a workaround running a python native function to build th efile I needed. Unfortunately I cannot afford more time with this issue, I didn't find the real reason and solution but it is clear is not something related with the normal SCONS performing but with the trick performed in the SPAWN.
scons_common.GenerateObjectsFile('../' + objects_file, components)

Get process executed by MONO on GNU/Linux

I am using MONO to execute an application. Using ps command shows eihter processname MONO or CLI.
How can I get the name of the application executed by MONO ?
Example : mono myApp.exe
I want to know, if myApp.exe is currently excecuted. Finally I want to do this check programmatically.
Cheers.
You usually will run your program from a shell script and there you can use the -a flag to exec:
#!/bin/bash
exec -a VisibleName mono program.exe
Here is a solution that uses .NET/MONO functions (no need to invoke native DLLs nor piping Shell Output):
List all processes.
If a process Name contains MONO or CLI then read
the commandline of that process
The commandline shall contain all
needed Information to identify your application
public static int process_count(string application_name)
{
int rc = 0;
string cmdline = "";
Process[] processlist = Process.GetProcesses();
foreach (Process p in processlist)
{
cmdline = "";
//Console.WriteLine("PID : " + theprocess.Id + " " + theprocess.ProcessName);
if (p.ProcessName.Contains("mono"))
{
Console.WriteLine("PID : " + p.Id + " " + p.ProcessName + " " + p.MainModule.FileName);
cmdline = File.ReadAllText("/proc/" + p.Id.ToString() + "/cmdline");
Console.WriteLine("CMDLINE : "+cmdline);
}
if (p.ProcessName.Contains("cli"))
{
Console.WriteLine("PID : " + p.Id + " " + p.ProcessName + " " + p.MainModule.FileName);
cmdline = File.ReadAllText("/proc/" + p.Id.ToString() + "/cmdline");
Console.WriteLine("CMDLINE : " + cmdline);
}
if (cmdline.Contains(application_name))
{
Console.WriteLine("Found existing process: {0} ID: {1}", p.ProcessName, p.Id);
rc++;
}
}
return (rc);
}
How to do it manually:
invoke ps -e to get all processes of MONO or CLI
Look up the PID e.g. 2845
Display command line : cat /proc/2845/cmdline
Note for newbies: this Approach is not dedicated to Windows OS as it does not Support the concept of /proc filesystem.
Cheers
Have a look at
getting-mono-process-info
The solution uses the same approach of reading /proc but has more options.
Cheers

How to write data to existing process's STDIN from external process?

I'm seeking for ways to write data to the existing process's STDIN from external processes, and found similar question How do you stream data into the STDIN of a program from different local/remote processes in Python? in stackoverlow.
In that thread, #Michael says that we can get file descriptors of existing process in path like below, and permitted to write data into them on Linux.
/proc/$PID/fd/
So, I've created a simple script listed below to test writing data to the script's STDIN (and TTY) from external process.
#!/usr/bin/env python
import os, sys
def get_ttyname():
for f in sys.stdin, sys.stdout, sys.stderr:
if f.isatty():
return os.ttyname(f.fileno())
return None
if __name__ == "__main__":
print("Try commands below")
print("$ echo 'foobar' > {0}".format(get_ttyname()))
print("$ echo 'foobar' > /proc/{0}/fd/0".format(os.getpid()))
print("read :: [" + sys.stdin.readline() + "]")
This test script shows paths of STDIN and TTY and then, wait for one to write it's STDIN.
I launched this script and got messages below.
Try commands below
$ echo 'foobar' > /dev/pts/6
$ echo 'foobar' > /proc/3308/fd/0
So, I executed the command echo 'foobar' > /dev/pts/6 and echo 'foobar' > /proc/3308/fd/0 from other terminal. After execution of both commands, message foobar is displayed twice on the terminal the test script is running on, but that's all. The line print("read :: [" + sys.stdin.readline() + "]") was not executed.
Are there any ways to write data from external processes to the existing process's STDIN (or other file descriptors), i.e. invoke execution of the lineprint("read :: [" + sys.stdin.readline() + "]") from other processes?
Your code will not work.
/proc/pid/fd/0 is a link to the /dev/pts/6 file.
$ echo 'foobar' > /dev/pts/6
$ echo 'foobar' > /proc/pid/fd/0
Since both the commands write to the terminal. This input goes to terminal and not to the process.
It will work if stdin intially is a pipe.
For example, test.py is :
#!/usr/bin/python
import os, sys
if __name__ == "__main__":
print("Try commands below")
print("$ echo 'foobar' > /proc/{0}/fd/0".format(os.getpid()))
while True:
print("read :: [" + sys.stdin.readline() + "]")
pass
Run this as:
$ (while [ 1 ]; do sleep 1; done) | python test.py
Now from another terminal write something to /proc/pid/fd/0 and it will come to test.py
I want to leave here an example I found useful. It's a slight modification of the while true trick above that failed intermittently on my machine.
# pipe cat to your long running process
( cat ) | ./your_server &
server_pid=$!
# send an echo to your cat process that will close cat and in my hypothetical case the server too
echo "quit\n" > "/proc/$server_pid/fd/0"
It was helpful to me because for particular reasons I couldn't use mkfifo, which is perfect for this scenario.

Resources