Using a script to run 2 programs, both with blocking functions - c++

I'm trying to run 2 C++ programs simultaneously. Both programs make use of inotify to each watch a folder for file creation, then handle the events (in a different manner) respectively. The programs also run indefinitely so they are forever watching their respective folders for new files.
I have a shell script that simply does the following:
./program1 -i input_file -o output_file
./program2 -i input_file -o output_file
I'm worried that because program1 is blocking and runs indefinitely, program2 will never get to execute. Is this the case? How should I work around this then?
Will ./program1 -i input_file -o output_file & ./program2 -i input_file -o output_file work?

Related

mpich2 2 executables standard output

I need to launch 2 executables (program1 and program2) with the same mpirun (mpich) command, and I'm trying to debug program1 with gdb. I use this command:
mpirun -n 1 gdb program1 : -n 1 program2
The command correctly opens the gdb console, but if I set a breakpoint somewhere after mpi_init, the screen gets flooded with the standard output of program2. Is there a simple way to redirect the standard output of program2 (only program2) to a file?
My fast solution was to hard-code a cut of stdout in program2, but I'm sure there must be a more elegant one ...
You could try this:
create a wrapper.sh that redirect the stdout and stderr to the file output :
cat > wrapper.sh << EOF
#!/bin/bash
\$* 1>>output 2>&1
EOF
make it executable
chmod +x wrapper.sh
mpirun with the wrapper
mpirun -n 1 gdb program1 : -n 1 ./wrapper.sh program2

system("command") produces an error; but it works when invoked directly from Bash prompt

I am trying to run the following bash command from my C++ program:
diff <(cat /etc/passwd) <(ls -l /etc)
with the following C++ statement:
system("diff <(cat /etc/passwd) <(ls -l /etc)");
The command works fine when running it directly from the Linux shell but when running it from my program, I get:
sh: 1: Syntax error: "(" unexpected
That's referring to the (
I have tried escaping the ( with a \, but that creates more issues:
system("diff <\\(cat /etc/passwd\\) <\\(ls -l /etc\\)");
sh: 1: cannot open (cat: No such file
All I want is to run the following from my C++ program:
diff <(cat /etc/passwd) <(ls -l /etc)
I can create a file and run it, but I leave that as a last option.
As mentioned system() creates a new standard shell sh and executes the commands. Since <() is a bash specific feature it can't be interpreted by sh.
You can circumvent this by calling bash explicitly and use the -c option:
system("bash -c \"diff <(cat /etc/passwd) <(ls -l /etc)\"");
or using a raw string literal:
system(R"cmd(bash -c "diff <(cat /etc/passwd) <(ls -l /etc)")cmd");
Here's the relevant part of the system(3) call manual page:
The system() library function uses fork(2) to create a child process
that executes the shell command specified in command using execl(3)
as follows:
execl("/bin/sh", "sh", "-c", command, (char *) 0);
system() returns after the command has been completed.
The system(3) call invokes /bin/sh to process the command. If you want specifically use bash features, you need to insert bash -c in front of the command string, which will run bash and tell it to process the remainder of the string.
system("bash -c \"diff <(cat /etc/passwd) <(ls -l /etc)\"");

How can make my makefile overwrite a file?

descript: progam.cpp
g++ progam.cpp -o descript
./descript 2>output.txt | tee -a output.txt
From my understanding, first command compiles program.cpp and the second command sends the output to both terminal and a textfile.
Is there a way to adjust this so that I :
Use "make".Go through program prompts. Output is saved in output.txt
Use "./descript" or some command a second time and overwrite output.txt with new output
I'm fairly new to linux commands in general so anything would help.
It may be helpful to include a make clean function in your Makefile.
Example make clean function could include:
make clean:
rm -f output.txt
Then, insert the make clean at the beginning of your descript portion of the Makefile to auto-remove the previous output.

Getting gdb to automatically load binary from core file

Can I get gdb to automatically load the binary that's specified in the core file?
Given a core file I now usually do:
gdb -c corefile
GNU gdb 6.8
...
Core was generated by `/path/to/binary'
Then i copy-paste that and run:
gdb -c corefile /path/to/binary
It seems like an unnecessary two-step process and yet I don't seen an obvious way of doing it based on the man page. Am I missing something?
You could just script it?
#!/bin/bash
gdb "`file "$1" | awk -F \' '{print $2}'`" "$1"
This is what I usually endup doing:
var=$(file corefile)
echo ${var##*from}
gdc() {
gdb -c "$1" "$(file "$1" | sed -r -e "s#.*execfn: '([^\']+)'.*#\1#")"
}
$ gdc corefile

Does g++ still generate an output file even if the program fails to compile/load?

I am compiling some C++ programs through a perl script using:
g++ -o out `find ./ -iname "*.h" -or -iname "*.cpp"`
This seems to generate an an out file every time, regardless of whether the program compiled successfully or not.
Whenever the script tries to run programs like this, it gets permission errors (weird since I'm running as root).
Is this accurate and if so, how can I prevent it?
Thanks.
The answer to your title's question ("Does g++ still generate an output file even if the program fails to compile/load?") is no:
% echo blah > test.cpp
% g++ -o out test.cpp
test.cpp:1: error: expected constructor, destructor, or type conversion at end of input
% ls *out*
/bin/ls: *out*: No such file or directory
%
I solved it as follows:
For some reason, trying to put the output executable using -o out seemed to force creating the file even after the compile failed (it seems to me).
g++ -o out.tmp `find ./ -iname "*.h" -or -iname "*.cpp"` && mv out.tmp out