Nodejs and UNIX newbie: run node command in a cpp program - c++

I'd like to run a nodejs program through the system() function in stdlib.h. I can run the bash command /usr/local/bin/node ~/some_folder/xml2js.js in terminal, but when I ran this:
int main(int argc, const char * argv[])
{
// insert code here...
//system("/usr/local/bin/node ~/some_folder/xml2js.js");
system("~/some_folder/run.sh");
std::cout << "Hello, World!\n";
return 0;
}
It told me node: command not found.
the run.sh is below:
#! /bin/bash
node ./xml2js.js
Are there any other ways to call other programs in UNIX? And how to get the output of the command into stdout?

Try writing the absolute path to that script. It should work.
You could try system("/home/$(whoami)/some_folder/run.sh") assuming that your user's home folder is in /home.
Also, does that script have execute permissions? Also, check the return code of system.

Related

Terminal command in a ROS package is not executed

I have a little problem with a ROS node even if i think that it's mainly a C++ code problem.
What i want to do is using a script that runs in the terminal (Ubuntu 14.04) within a ROS node.
I'm doing this using the system() command code of the C++ language.
This script has to elaborate a .txt file stored locally on my PC; when i use the script by a normal command line method, obviously i have to navigate to the directory where my script lies first, and then i launch the script.
To replying this on my node, i use 2 system() instances to navigate to the directory and then to run the script.
The problem is that it seems that the node "cannot see" the command which tells it to navigate to the correct directory, so, all i can obtain is an error saying: cannot read the text file.
The only way to start the script correctly is to launch the node after i manually navigate to the directory where it lies the script.
I'm posting the code below, maybe I'm writing something bad or there is another problem that i can't see, since i'm a noob in the world of ROS and coding in general. Thank you in advance, i know that maybe it's a stupid question!
Marco
Here it is the code:
int main(int argc, char **argv)
{
ros::init(argc, argv, "heart_rate_monitor");
ros::NodeHandle n;
system("cd ~/home/marco/catkin_ws/src/heart_rate_monitor");
system("get_hrv -R test.txt");
exit(0);
return 0;
}
Note: i tried also without the ~ .
EDIT: now it seems that's running correctly, here it is the code:
int main(int argc, char **argv)
{
ros::init(argc, argv, "heart_rate_monitor");
ros::NodeHandle n;
chdir("/home/marco/catkin_ws/src/heart_rate_monitor");
system("get_hrv -R test.txt >doc.txt");
exit(0);
return 0;
}
Use chdir to change directory. System will create a new shell and execute the cd command. Please refer to this stack overflow post for more information.
As neo pointed out, the first system call is changing the current directory of the system call, but it does not influence the parent's (i.e. your node's) current directory.
But, if I may, you should try to solve this differently. Apart from hardcoding the path being wrong, you generally should not assume to have access to the source folder on runtime (e.g. if you do an install, the source could be anywhere). Instead:
put additional data in a new directory (e.g. 'data')
add an install target
retrieve the runtime path to your package using ros::package::getPath('your_package_name') and use the full path + "/data/test.txt" in your system call

Getting Environment Variable $PATH in Linux using C++ in Eclipse

I am trying to get the value of environment variable $PATH in Linux using a simple C++program as bellow:
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main ()
{
// get PATH using pipe
FILE* pip = popen("exec bash -c 'echo $PATH'", "r");
if (!pip)
{
printf("can not open pipe!");
return 1;
}
char lineversion[600];
memset (lineversion, 0, sizeof(lineversion));
if (!fgets(lineversion, sizeof(lineversion), pip))
{
printf("fgets error!");
return 1;
}
std::cout << lineversion << std::endl;
// get PATH using getenv
char* pPath = getenv ("PATH");
std::cout << pPath << std::endl;
}
I used two different methods: using pipe and using getenv method. They both output this:
/opt/texbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/netbeans-7.3.1/bin
Interestingly the actual value of PATH is something different!
Why my C++ program is showing a different value for PATH?
Edit 1: I am running my C++ program in Eclipse IDE.
Edit 2: Compiling the program directly (without Eclipse IDE) shows the correct PATH value!
Edit 3: I found the answer in here too.
A process inherits the environment from the process that created it.
This is how Linux works, along with many other operating systems.
If you launch a program from Eclipse, that program inherits Eclipse's environment.
If you launch a program from the shell, that program inherits the shell's environment, including the modifications to PATH you have in your init files.
Since Eclipse has inherited its environment from whichever process launched it, you should see the expected output if you launch Eclipse from the shell instead of through your desktop GUI.

c++ for unix command line operation

I have a remote unix shell which I log on often to checkout files with but the system keep resetting my locals setting when I logon to it.
I was planning to write the code to execute a list of commands when I log on.
#include<iostream>
#include<stdlib.h>
int main(){
char javah[]="JAVA_HOME=/appl/usr/jdk/jdk1.6.0_20";
char anth[]="ANT_HOME=/appl/usr/ant/instances/1.8.2";
char path[]="PATH=$ANT_HOME/bin:$PATH";
system("bash");
system("cd");
system("cd insurancePPC.11");
system("0x0C");
system("ls");
putenv(javah);
putenv(anth);
putenv(path);
std::cout << "JAVA_HOME=" << getenv("JAVA_HOME");
std::cout << "\n";
std::cout << "ANT_HOME=" << getenv("ANT_HOME");
std::cout << "\n";
std::cout << "PATH=" << getenv("PATH");
std::cout << "\n";
system("cd tools");
std::cout << "command executed successfully...\n";
return 0;
}
Can anyone tell me why this wasn't working as expected?
cd is a built in command of the shell and only affects the current process (i.e. the current running shell.)
When you run system("cd insurancePPC.11"); it starts a new shell, that new shell changes the directory to insurancePPC.11 and exits. Your own process is unaffected by that cd command.
You are much better off writing these commands in a text file and run it as a shell script via the source command.
Create a file named myenv.sh with this content:
JAVA_HOME=/appl/usr/jdk/jdk1.6.0_20
export JAVA_HOME
ANT_HOME=/appl/usr/ant/instances/1.8.2
export ANT_HOME
PATH=$ANT_HOME/bin:$PATH
export PATH
cd
cd insurancePPC.11
ls
echo JAVA_HOME=$JAVA_HOME
echo ANT_HOME=$ANT_HOME
echo PATH=$PATH
cd tools
And from your command line run source myenv.sh Or if your shell supports it, use the shorthand . myenv.sh
There's no need to write a C program here. Just save the following as mysettings.sh:
export JAVA_HOME=/appl/usr/jdk/jdk1.6.0_20
export ANT_HOME=/appl/usr/ant/instances/1.8.2
PATH=$ANT_HOME/bin:$PATH
cd tools
When you log in, run
. mysettings.sh

How can I get stdio output when running application as root?

I'm trying to run my application as root because I need to access low level hardware on my computer.
When I run the command:
./application_name
...it works, except gives an error that it needs root. However, when I run this:
sudo ./application_name
...I get no terminal ouput.
I've tested that every time that I run an executable on Linux as root, it doesn't print anything to terminal. How can I fix this?
Edit: somewhat of a test case provided (mobile so can't type out much):
sudo g++ test.cpp -o executable
sudo chmod +x executable
This works on Debian:
./executable
This doesn't:
sudo ./executable
test.cpp:
#include <iostream>
int main() {
std::cout << "Hello World!";
}
That behavior is really strange. Root permissions for that application should have no effect on std output.
For example, I made a simple test, a "hello world" that I ran as root on Debian OS and I had output in terminal.
A simple test to convince yourself that you should have the output, is to make a redirect to a file. For example sudo ./executable > output.txt and you'll see that everything should be OK.
Note that it should be strange if you don't have output from a simple "hello world".

Try to execute command line codes from c++ linux

I tried the following code, to communicate with the command line from c++ code.
#include<iostream>
#include<cv.h>
int main()
{
system("gnome-terminal");
system("cd");
}
The gnome-terminal command is executing fine. After I close the terminal, when am expecting the cd to execute, however, is not happening. Could you please help me and point out the reason? Thanks. I was expecting the function to make the cmd go down to the home directory
, but it did not. am working in linux
I tried it even by removing gnome. simple cd is not working. am I doing something rong>?
If I try ls, it seems to be working fine!
My main aim is to open a new terminal, and execute commands on that new terminal through the present program that opened the new terminal. Could you please tell me how I can achieve this??
If you want to run a program and wait for it to finish before executing next line, take a look at this page and example code here: http://www.thegeekstuff.com/2012/03/c-process-control-functions/
But if you want to run gnome-terminal and execute a command in newly created window, do this:
system("gnome-terminal -x sh -c 'cd /tmp ; ls -la'");
The system function creates a shell child process to execute the specified command.
cd is a shell command which changes the current working directory of that shell process only.
So the child's cd probably works fine, but it has no effect on your C++ program, which is a different process.
Instead, you probably want to look at the Linux system call chdir.
Thanks for your help!! This command worked perfectly fine from this link
https://superuser.com/questions/198015/open-gnome-terminal-programmatically-and-execute-commands-after-bashrc-was-execu
gnome-terminal -x sh -c 'command1; command2; exec bash'
and I entered the respective commands in the new window. But to change the working directory in the shell am working o, I haven't still figured that out.