I created a program that should rename some files
system("rename file.txt file2.txt"); // examples only
did run fine at cmd , but not powershell
rename : The term 'rename' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ rename
+ ~~~~~~
+ CategoryInfo : ObjectNotFound: (rename:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
by This article from MS , powershell should use rename-itemHowever , I don't know any "trick" to determine whther programs ran by powershell or cmdA post for determine program's run by which , uses process checking which I find it hard to implement ( they said use wmic.exe , but I don't know how to and further research needed to be )
The conclusion:
How to determine whether my programs runs on powershell or cmd by C++ ?
Is it possible, by knowing the console used ( programmingly ) , my programs could use if-else method to change the command?
Edit: for the time being , My program's method is read file.txt and paste it in file2.txt ( examples only )..Basically like copy and paste to another renamed file and use system("del file.txt");
How to determine whether my programs runs on powershell or cmd by C++
While that is possible, it also irrelevant to your use case, because the shell that launched your program is your program's parent process (to which you cannot submit commands).
Since your program must launch its own shell (child) process in order to execute a shell command, you're free to choose which shell to invoke .
The system() C library function targets the host platform's default shell, which is cmd.exe on Windows (and /bin/sh on Unix-like platforms), so your command - which uses the internal cmd.exe rename command - will work fine, irrespective of whether your program was invoked from PowerShell or cmd.exe.
Related
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.
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.
How can I open a new terminal from C ++ code and write inside it. I know how to open new terminal by using system command (system("/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal")), but do not know how to write string in it ? I'm working on an operating system mac os.
In Linux you can do so
std :: string cmd = "gnome-terminal-x sh-c 'ls-l; exec bash'";
system (cmd.c_str ());
how to do it in the mac os ?
Your basic mechanism of calling system() should still work, you just need a different command.
One way to do this is by running AppleScript from the command line via osascript. You can use the "AppleScript Editor" application (and use the Library command in its Window menu) to learn more about all the commands that can be given to programs in this way.
For example, to make the Mac Terminal run top, I could invoke this command line:
/usr/bin/osascript -e 'tell application "Terminal" to do script "top"'
Similarly, if I'd already written an entire file of commands to run, I could give it a .command extension and ask Terminal to open the file instead:
/usr/bin/osascript -e 'tell application "Terminal" to open "/Users/me/Desktop/MyFile.command"'
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.
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.