Hi im working on a simple bash coding i don't know how to accomplish this and this might be easy for you guys please help.
I have a simple program on file.sh
#!/bin/bash
./program
This ./program is a compiled version of C program which i complied using GCC im trying to use at in bash script to execute this program for few seconds and then terminate that after x interval time and restart again.
I hope you got my point?
Example: Run file.sh for 10 sec and I'll display the result from ./program C program and then after 10 sec it will restart again.
The answer is, if I understand correctly, a combination of sleep and timout:
while :; do
timout 10s ./program
# display some results
sleep 10
done
You can use the sleep command. For example: exec ./program && sleep n where n is the time you want the command to sleep. If you want you could put it in a while loop inside an sh script and run it continuously.
To run it continuously until you close the terminal:
while true
do
echo "[CTRL+C] to stop..."
timeout 10s ./program
done
Related
How do you kill a running process in a bash script without killing the script?
Goal
So... I need to kill a running process to continue with the execution of my script.
Here´s a stripped down version of my script:
# Setup
echo "Use ctrl+C to stop gathering data..."
./logger
#------------------
echo "Rest..."
I need to be able to kill ./logger without killing my script
Expected vs Actual Results
I was expecting a result like this:
Use ctrl+C to stop gathering data...
^C
Rest...
but it stops when I kill the program
use ctrl+C to stop gathering data...
^C
The ./logger command is a C program that already handles the SIGINT signal (Ctrl + C) but it won't stop until it receives it.
Is there a way to stop the program without killing my script?
The C Program is not important but it looks something like this
#include <stdio.h>
#include <signal.h>
int flag = 1;
void handler(int i)
{
flag = 0;
}
int main(int argc, char** argv)
{
signal(SIGINT, handler);
while(flag)
{
usleep(10000);
}
}
If you type control-C at the terminal where the script is running, the signal goes to all the processes — the logger program and the script. And the script terminates because you've not told it to ignore signals while the logger is run. You can do that using the trap command but you'll need to undo the trapping before running the C program. See the Bash manual on Signals too.
For example, I have a program dribbler that generates messages, one every second by default, but it is configurable. I'm using it as a surrogate for your ./logger program. The -m options specifies the message; the -n option requests that the messages are numbered, and the -t option specifies output to standard output (instead of a file which it writes to by default).
#!/bin/bash
#
# SO 6418-0134
program="dribbler -t -n -m Hello"
echo "About to run '$program' command"
trap "" 2
(trap 2; $program)
echo "Continuing after '$program' exits"
sleep 1
echo "But not for long"
The sub-shell is necessary. When I run that script (trapper.sh), I get, for example:
$ bash trapper.sh
About to run 'dribbler -t -n -m Hello' command
0: Hello
1: Hello
2: Hello
3: Hello
^CContinuing after 'dribbler -t -n -m Hello' exits
But not for long
$
Incidentally, POSIX defines a command logger that writes messages using the syslog() function(s) to the syslog daemon.
It might also be worth reviewing the Q&A about Sending SIGINT to forked exec process which runs a script does not kill it, especially the accepted answer and its links to Q&A on other Stack Exchange sites, as it matters that you and I both executed a C program, not a shell script.
I have a C program that I want to run without having to manually type commands into. I have 4 commands (5 if you count the one to exit the program) that I want given to the program and I don't know where to start. I have seen some stuff like
./a.out <<<'name'
to pass in a single string but that doesn't quite work for me.
Other issues I have that make this more difficult are that one of the commands will give an output and that output needs to be a part of a later command. If I had access to the source code I could just brute force in some loops and counters so I am trying to get a hold of it but for now I am stuck working without it. I was thinking there was a way to do this with bash scripts but I don't know what that would be.
In simple cases, bash script is a possibility: run the executable in coproc (requires version 4). A short example:
#!/bin/bash
coproc ./parrot
echo aaa >&${COPROC[1]}
read result <&${COPROC[0]}
echo $result
echo exit >&${COPROC[1]}
with parrot (a test executable):
#!/bin/bash
while [ true ]; do
read var
if [ "$var" = "exit" ]; then exit 0; fi
echo $var
done
For a more serious scenarios, use expect.
Pretty simple, I need to test a C program by inputting a large number of integers into it. To do this, for this particularly case, I need to run the program, then when it waits for user input (scanf("%d, integer)), I need to give it the integer from the loop I'm currently at.
right now I have
for i in {1..5};
do
(echo -n "$i" && ./a2 $i)
done
but it still just waits for user input, then after user input is given, prints the integer of the loop I'm on. I've tried a few examples from similar problems I've found on stack exchange and elsewhere but so far no luck. I haven't ever really needed to mess about with shell scripting before so it's probably something simple I'm doing backasswordsly but no one else has done wrong before.
Try this!
for i in `seq 1 1000`; do echo $i | ./a2; done
Your solution
echo -n "$i" && ./a2 $i
would pass $i as argument for a2 not input.
I think what you need is not usually done using shell script.
You can write a c code to generate your input, which in this case is numbers from 1-10000. Let that file be testGenerator.c. Then, run this on your terminal:
gcc testGenerator.c
./a.out >input
This will create a file, named input which will have numbers from 1 to 10000, which is of course the o/p of testGenerator.c.
Then, if your program, in which you want input is compiled into a2, as I can see, you can run it as:
./a2 <input >output
and you will get the required output in the file output. If you don't write >output here, you will see o/p on terminal.
Also, when you are running this script, you are actually running the a2 10000 times and giving a number as command line argument, which is very different from taking input from stdin which of course, scanf does.
for i in {1..1000}; do echo $i | ./a2; done
I want to run a command with different arguments in multi-threading form,
What I tried is:
#!/bin/bash
ARG1=$1
ARG2=$2
ARG3=$3
for ... #counter is i
do
main command with ARG1 ARG2 ARG3 & a[i]=$!
done
wait `echo ${a[#]}`
I used & a[i]=$! in for loop and wait $(echo ${a[#]}) after for loop. I want my bash to wail till all threads finish then echo their pid for me...
But when I run my script after some time it waits.
Thank you
I think you want this:
#!/bin/bash
for i in 0 1 2
do
sleep 3 & a[$i]=$!
done
wait
echo ${a[#]}
You are missing the $ on the array index $i in your script. Also, you don't need to say which PIDs you are wating for if you are waiting for all of them. And you also said you wanted to see the list of PIDs at the end.
I have a program written in C that operates similar to the below output.
WELCOME TO PROGRAM.
Hit 1 to do task 1.
Hit 2 to do task 2.
Hit q to quit.
What i need is a bash shell script that start the program, then enters 1, 2 and q into the program so i can test all the functionality in one command.
I would assume it to look similar to the following
#!/bin/bash
./start kernel
1
2
q
You can use a "here document" . The syntax looks like this:
./start kernel <<EOF
1
2
q
EOF
"EOF" can be whatever unique word you want, as long as it isn't something you'll actually need in the input.
Typically you use expect for testing these types of applications.
You can save your input in a text file - input.txt and execute your program this way: ./program < input.txt
I do this:
#! /bin/bash
printf "1\n2\nq\n" | ./start kernel
You can think of shell scripts as what they are... just each line being executed in an (albeit new) shell.
A simple way to do this sort of input is, assuming [your program] accepts stdin, is:
#!/bin/bash
echo "1" | [your program] > [logfile1]
echo "2" | [your program] > [logfile2]
echo "q" | [your program] > [logfileq]