Hiding console command used while using system()? C++ Linux - c++

Well, I will put it plain and simple: I am a C++ pleb. Still trying to learn though.
My question is: is it possible to run a command though the terminal using system() command without letting the command be shown in the console/terminal?
Example:
system("sudo service sshd start") ;
Output: Sudo service sshd start
Where as I want:
system("sudo service sshd start") ;
output: (Blank)
Note: I am on linux.

The system standard library function starts up a subshell and executes the provided string as a command within that subshell. (Note that a subshell is simply a process running a shell interpreter; the particular shell interpreter invoked by system will depend on your system. No terminal emulator is used; at least, not on Unix or Unix-like systems.)
The system function does not reassign any file descriptors before starting the subshell, so the command executes with the current standard input, output and error assignments. Many commands will output to stdout and/or stderr, and those outputs will not be supressed by system.
If you want the command to execute silently, then you can redirect stdout and/or stderr in the command itself:
system("sudo service sshd start >>/dev/null 2>>/dev/null") ;
Of course, that will hide any error messages which might result from the command failing, so you should check the return value of system and provide your own error message (or log the information) if it is not 0.
This really has very little to do with the system call or the fact that you are triggering the subshell from within your own executable. The same command would have the same behaviour if typed directly into a shell.

Related

gdb - how to make it call a program with a relative name [duplicate]

I am trying to launch a legacy application in GDB, and it requires that it's argv[0] value not contain anything other than alphanumeric characters.
Whenever I launch the program in GDB it seems that it expands the name to be the full path before running the program, so I get an error like (because it can't deal with the slashes):
"Cannot find /home/user/myapp ..."
Is it possible to run a program in GDB with a relative path, so that it will just see "myapp"?
Gdb normally runs target commands using the shell command line
exec program_pathname program_arguments
But it has a set exec-wrapper command that will change this to
exec exec_wrapper program_pathname program_arguments
The exec_wrapper is often another command, but it can be an option that the exec command accepts.
Many shells (bash, zsh, ksh93) support a -a option to the exec command to set argv[0].
So, if your shell supports exec -a, you can do the following to invoke /home/user/myapp with argv[0]==myapp:
(gdb) set exec-wrapper -a myapp

How to run iostream system command in the same thread?

I'm trying to execute a command using std::system from Unreal Engine C++
FString command = FString("start /B cmd /k python \"D:/app.py\"");
std::string comm(TCHAR_TO_UTF8(*command));
std::system(comm.c_str());
The command itself is working as expected, however, I need it to execute on the current thread, or alternatively check if it's finished before continuing because the next operations depend on the completion of this command
Is there a way to do it? or maybe I should use another command?
Thanks, Eden
The std::system function will not return until the command you execute have finished running.
Also on Windows (which you seem to be running) then system will invoke the command interpreter (cmd) for execution of the command, which means the command you want to execute must be in the command interpreters PATH (or be an internal command of the command interpreter).
If python is in the PATH, then you could run the python command directly, without using start or cmd (especially since then you would have two instances of cmd running), and the system function would block and not return until the python command finished running:
FString command = FString("python \"D:/VRoscopy_repo/VRoscopy/conversion/invesalius3-master/app.py\" --no-gui -i \"D:\VRoscopy_repo\DICOM\Human\MedDream\Body\" -t 200,3033 -e \"D:\VRoscopy_repo\DICOM\Human\MedDream\Body/VRoscopy27777BED4B650CE6AFE884B365C56BCC.stl\"");

How do I open a terminal window with C++ in Ubuntu?

I recently decided to start teaching myself C++ and thought a simple encryption project would be a good place to start, since it covers most of the basics (cout, cin, opening files, etc). Is there a way to have the code open a terminal window similar to the one opened when I compile and run from sublime text?
I have tried this so far, but it hasn't changed anything.
string cmd = "gnome-terminal-x sh-c 'ls-l; exec bash'";
system(cmd.c_str());
Essentially, I would like to be able to run the program by clicking the .exe, and have the terminal where all of the input and output goes pop up.
You don't need to write any code, you just need to configure the shortcut to launch the program in a terminal. Here's a Gnome dialog that shows that option:
Problem seems to be gnome-terminal, or then just my failure to give it the right arguments. For example gnome-terminal -x sh -c 'ls -l ; exec bash' from command line in another terminal just opens an empty gnome-terminal and spits out a bunch of glib warnings to original terminal... (Note to readers: if you can give the right command that works for gnome-terminal, please let me know in comments or just edit this paragraph.)
However, using xterm works, for example xterm -e sh -c 'ls -l; exec bash', or a line for your code:
string cmd = "xterm -e sh -c 'ls -l; exec bash'";
As a side note, the command to open the default x terminal window of the DE is x-terminal-emulator, but it quite often has the practical problem of different terminals taking different arguments, so sadly you're probably better of using a specific terminal, like that xterm, and requiring that to be installed, or letting user to configure what terminal to use, with what arguments (though letting user to specify any command to be run can also be a security risk, if user is not always trusted).
Just be very careful with escaping. For example, when you test the command form command line, and then copy-paste it to C++ string literal, you need to escape every " and \ one more time for C++. If you have trouble with this, check out C++11 raw strings.
Escaping becomes extra important if you construct the command string at runtime, and especially if you accept user input and add that to the string. In that case, better search for and use some existing library like GLib, or sanitize the user input very carefully (ie. just paranoidically reject anything with chars, which may have a special meaning in shell in some context).
If you are actually asking, how can my program open a console window for itself similar to how Windows console programs behave, and redirect it's own stdin, stdout and stderr there, as if it was launched from command line, that that is not very easy from the same binary, and it is not commonly done like that in Unix.
If you want a behaviour like that, you could create a desktop shortcut, but more general way is to write a wrapper shell script, which starts your binary in a terminal. What kind of script exactly, depends on how you want it to behave exactly: what will it do with stdio, will it return or wait for program to exit, how do you want it to find the binary, how does it behave when run from command line instead of double-clicking from GUI, etc.

What is the difference between calling a script from the shell and using system()?

I have built a bash script to start up some processes in my system. It simply calls the process and associated config file. Same as I would call from the command line.
#!/bin/bash
# Start specified process in a new session
setsid $1 &>/dev/null &
So to start up someprocess, I would call from the command line:
root#supercomputer:~# start someprocess
This works like a charm. Every process, every time. But when I make a system call from a different running C++ process, someprocess never starts up.
system( "start someprocess" )
This approach for 90% of my processes, except for one. The only difference in the working and not working processes is that the non-working one uses proprietary libraries underneath. I recently added the setsid option to the bash script in hopes that starting a new session would help, but it made no difference. I've also tried popen, and execv. No change.
So my question is what is the difference between calling something with system() and just making that same call from the command line?
All processes are written in C++ on Linux.
.bashrc is only invoked if bash is run as interactive, non-login shell. If it's invoked as non-interactive shell, as when using system() on a script with a bash shebang, it only reads the configuration file pointed to by $BASH_ENV.
That means you have the following options:
add -l to the shebang - causes the shell to read ~/.profile at startup
set $BASH_ENV to the script you want sourced before calling system()
add -i to the shebang - invokes bash as interactive shell and causes it to read ~/.bashrc, but will also effect how bash handles input/output.
I'd recommend the first option.
You can find a detailed explanation of how bash reads it's startup files here. I'm not sure this will solve your problem completely, but it may at leas shed some light on that part of the issue.
Check the environment variables that are used in the system() call. For example, call system to print out some of the variables, and see if they match what you see from the command line.
Likely they are not being sourced correctly.

C++ Keep process alive after it kills its parent

I'm working on implementing a self-updater for a daemon on OS X. The update is published as a .pkg file, so what I'm trying to do is as follows:
When the daemon is notified that an update is available, it calls installer via the system() call to install the package. The package contains a newer version of the daemon, a preupgrade script that stops the daemon (launchctl unload /Library/LaunchDaemons/foo.plist), and a postflight script that starts it back up after the new version is installed. The problem I'm having is that the installer process is quitting prematurely. I suspect that it may be because the installer kills its parent process in order to update it, and then gets killed itself instead of continuing as its own orphan process. I've tried the following with no luck:
Postpending the installer command with '&' to run it in the
background
Wrapping the installer command with nohup
The install command completes consistently without error when I run it from the command line, and fails consistently when run from the installer. When called from the installer, I'm piping the output to a file, and sometimes it has nothing, and sometimes it shows the install getting to about 41% completion before output stops. Any ideas on how I can figure out what's happening to the process or make sure it stays alive without its parent?
When you call launchctl unload, it kills the entire process group (unlike a simple kill). You want to move your subprocess into a separate process group. The easiest way is with the C call setsid().
If you're in the middle of a shell script, you should look at the following approaches. I haven't tried these since I was dealing with a C program and could setsid():
Prior to calling the installer, use set -m. This is supposed to turn on monitor mode, which says "Background processes run in a separate process group and a line containing their exit status is printed upon their completion."
Try this sub-interative shell trick: New process group in shell script