A simple question:
I'm using
system("mkdir /some/dest/");
on my program. How do I disable its output to the screen when running my program because if the dir exists, I get "mkdir: cannot create directory `/some/dest/': File exists"
Tried to run
system("mkdir /some/dest/ > /dev/null");
but it didn't work
Thanks
It's a weird way to create directories from C code, taking into account that mkdir (1) itself is just a wrapper for mkdir (2) system call.
I'd recommend using mkdir (2).
P.s. By (2) I mean man category of documentation ($ man 2 mkdir), this is a category for system calls.
There are two streams, stdout and stderr. You are redirecting only strout, not stderr.
You need to redirect stderr to /dev/null as well; read your shell manual. In bash I think you can do:
mkdir /some/dest/ &> /dev/null
This answer your question about how to hide error messages when calling system(), but the advice from other answers (using native C function mkdir) is more C/C++ idiomatic.
Related
Working on a C++ Unix program executed on the command line (MacOs).
I call system("history -s SOMETHING") in it to add SOMETHING to the history of the user's shell, but I guess the call is opening a new sub-shell.
My question is : can I execute the system call on the "current" shell (the one used to run the program) ?
To be clear I want to find the SOMETHING in my shell history when I quit the program.
Thanks !
As far as I know, it's not possible in general.
If you're using bash, and since this is only for you:
Enable history appending in .bashrc:
shopt -s histappend
Launch a login bash shell in main:
system("bash -li -c 'history -s SOMETHING'");
and then refresh your history:
history -n
The history -n can be automated - you can execute it inside your prompt, for instance.
Figuring out how to do that left as an exercise.
(Disclaimer: I have only tried this in Ubuntu under the Windows Subsystem for Linux, but it should work very similarly on a Mac.)
It isn't possible. The usual work around -- not applicable if there is other wanted output -- is to make your program prints the wanted command and then execute it. For instance
#include <iostream>
int main() {
std::cout << "history -s SOMETHING\n";
return 0;
}
and then
eval $(/path/to/my/exe)
For ease of use, you can put that in a shell function
myfn() {
eval $(/path/to/my/exe)
}
that you can simply use
myfn
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.
When I directly run a command in my Linux terminal, say "ls", the output is with color. However, when I run a C++ program which calls system("ls"), the output does not have color.
Is there way to get the latter way to also display colored output?
Thanks!
The answer for why there's no color lies here.
system() executes a command specified in command by calling /bin/sh -c
command, and returns after the command has been completed.
sh -c ignores aliases. Perhaps somewhere you have an alias where ls means ls --color=auto.
So for example, if I do sh -c 'ls', I will get no color.
Proof:
wow ♪[01:04 AM][vnbraun#chernobyl ~]$ which ls
alias ls='ls --color=auto'
/bin/ls
wow ♪[01:08 AM][vnbraun#chernobyl ~]$ sh -c 'which ls'
/bin/ls
Therefore, you can try doing system("ls --color=auto");.
You could run
system("/bin/ls --color=auto");
But I don't think you really should run ls from your C++ program. Perhaps you want to use -some combination of- readdir(3), stat(2), nftw(3), glob(3), wordexp(3) etc etc....
I don't think that forking a shell which then runs /bin/ls is useful from a C++ program. There are simpler ways to achieve your goal (which I cannot guess).
You probably should read Advanced Linux Programming
Try invoking ls --color=auto or ls --color=always to display ls with colors.
This is likely due to a bash configuration file somewhere in your system aliasing "ls" to "ls --color".
Using "ls --color" in your program should work.
I am using C++ on Ubuntu. I have been using the command:
system("mkdir new_folder");
to make a new folder called new_folder. However, if that folder already exists, C++ outputs an error message (and continues to run afterwards).
Is there a way to stop the error message from printing out?
For this particular command use mkdir -p new_folder.
Generally, you want to fork your process and on one of the branches redirect stdout and stderr to /dev/null or similar then do exec to replace the process with the new one.
I have 3 questions. I am making a C++ executable to launch a Perl program I made. I will compile it for Winows, Mac OSX and Linux. It's pretty much just: system("perl progam.pl");
When compiled with Mac OSX, the program starts in ~. How would I get it to start in the dir it was launched from, or is it just a problem with the compiler?
I'm using - echo -n -e "\033[0;Program\007" - in an attempt to make the windows title "Program". Is this is best way?
I'm using - echo -n -e "\033[7;30;47m" - to make the background of the window black. Is this the best way?
Thanks.
This sounds like something Finder is doing. Launching the app from a shell should work as you expect.
Use tput
See answer to 2, above.
On Mac OS/Unix, invoking system does not change the current working dir. When executing program.pl the current working directory is the same from which you executed the C++ executable. When you launch the executable using Launch Services (e.g. the Finder) the working directory should be /.
On #1 you can refer to the current directory with ./ so system("perl ./progam.pl"); should do it assuming both scripts are sitting in the same folder. ../program.pl would be one level higher.
For #1, use getcwd & then pass an explicit path to system:
cwd=getcwd(NULL, PATH_MAX);
sprintf(cmd, "perl %s/program.pl", cwd);
system(cmd);
free(cwd);
If your perl program itself relies on a specific working directory, then do this instead:
sprintf(cmd, "cd %s && perl program.pl", cwd);
This is probably a silly question, but why are you making an application to launch a perl script? Just add the following to the top of your perl script and use "chmod a+x" to make it executable:
#! /usr/bin/perl
When you use the system command from C and C++, you are basically launching the default system shell and executing the given command in that shell. Doing that is not very portable and somewhat defeats the purpose of using C or C++ (since you could simply create a shell script that does the same thing). If you want to actually do this with C++, you should probably use popen or fork+exec to launch perl. Generally speaking, it isn't nice to end users to play with their Terminal in the manner that you have proposed; most users, by default, have the Terminal configured to display the most recently executed command or their current directory or some other information of their choosing, and changing that is -- on UNIX systems such as Mac OS X and Linux -- considered improper etiquitte. If you are trying to create a terminal interface, though, you might want to look at the curses library.