Run the same bash script in multiple processes - linux

I have a bash script that basically translates an argument to a kubectl command. For example:
$ ./file.sh service1 (will run command kubectl logs service1- -n namespace -f)
or
$ ./file.sh service2 (will run command kubectl logs service2- -n anothernamespace -f)
My problem is that when I run it to see the logs live with option -f (follow) and I want to open another terminal tab to see the logs from another service with the same script, the first process is killed. So how can I run the same script from multiple terminals without stopping eachother and seeing the output for all.

Run the program in the background and output the log to out.file
command >> out.file 2>&1 &

I did manage to get it working with the help of ChatGPT (it does wonders). The solution is this:
osascript -e 'tell application "Terminal" to do script "clear; ./your_script.sh arg1 arg2" in the front window'

Related

Why doesn't tcpdump run in background?

I logged in a virtual machine via ssh and I tried to run a script in background, the script is shown below:
#!/bin/bash
APP_NAME=`basename $0`
CFG_FILE=$1
. $CFG_FILE #just some variables
CMD=$2
PID_FILE="$PIDS_DIR/$APP_NAME.pid"
CUR_LOG_DIR=$LOGS_RUNNING
echo $$ > $PID_FILE
#Main script code
#This script shall be called using the following syntax
# $ nohup script_name output_dir &
TIMESTAMP=`date +"%Y%m%d%H%M%S"`
CAP_INTERFACE="eth0"
/usr/sbin/tcpdump -nei $CAP_INTERFACE -s 65535 -w file_result
rm $PID_FILE
The result should be tcpdump running in background, redirecting the command result to file_result.
The script is called with:
nohup $SCRIPT_NAME $CFG_FILE start &
And It is stopped calling the STOP_SCRIPT:
##STOP_SCRIPT
PID_FILE="$PIDS_DIR/$APP_NAME.pid"
if [ -f $PID_FILE ]
then
PID=`cat $PID_FILE`
# send SIGTERM to kill all children of $PID
pkill -TERM -P $PID
fi
When I check the file_result, after running the stop script, It is empty.
What is happening? How can I solve it?
I found this link: https://it.toolbox.com/question/launching-tcpdump-processes-in-background-using-ssh-060614
The author seems to have faced a similar issue. They debate about race conditions, but I didn't understand completely.
I'm not sure what you're trying to accomplish by having the startup script itself continue to run, but here's an approach that I think accomplishes what you're trying to do, namely start tcpdump and have it continue to run immune to hangups via nohup. I've simplified things a bit for illustrative purposes - feel free to add any variables back as you see fit, such as the nohup.out output directory, TIMESTAMP, etc.
Script #1: tcpdump_start.sh
#!/bin/sh
rm -f nohup.out
nohup /usr/sbin/tcpdump -ni eth0 -s 65535 -w file_result.pcap &
# Write tcpdump's PID to a file
echo $! > /var/run/tcpdump.pid
Script #2: tcpdump_stop.sh
#!/bin/sh
if [ -f /var/run/tcpdump.pid ]
then
kill `cat /var/run/tcpdump.pid`
echo tcpdump `cat /var/run/tcpdump.pid` killed.
rm -f /var/run/tcpdump.pid
else
echo tcpdump not running.
fi
To start tcpdump, just run tcpdump_start.sh.
To stop the tcpdump instance started with tcpdump_start.sh, just run tcpdump_stop.sh.
The captured packets will be written to the file_result.pcap file, and yes, it's a pcap file, not a text file, so it helps to name it with the proper file extension. The tcpdump statistics will be written to the nohup.out file when tcpdump is terminated.
I too had faced problems when running tcpdump over an SSH session.
In my case, I was running
sudo nohup tcpdump -w {pcap_dump_file} {filter} > /dev/null 2>&1 &
Where, running this command over Paramiko SSH session as a background process was the problem.
To get around this, I used screen utility of Linux.
screen is an easy to use tool for long-running of processes as a service.
Might be an old post, but this is also relevant. I couldn;t understand why no file was being created only to realise that the file might not be created until a certain amount of data had been captured.
https://github.com/the-tcpdump-group/tcpdump/issues/485

Script to launch a linux terminal, wait 1s and then launch command in it

would like to automate showing of a nice weather report
curl wttr.in/bydgoszcz
weather report
with such script launched from the system menu:
#!/bin/sh
exec io.elementary.terminal -e "curl wttr.in/bydgoszcz"
But this way the output gets a little "incomplete", just like if the command got executed too fast (notice where the user#machine line went here):
weather report in the script
So, is there a way to delay the command after -e flag?
Or maybe totally different approach will automate this to show the output properly?
im not sure but try this
exec io.elementary.terminal -e "sleep1s & curl wttr.in/bydgoszcz"
Would
#!/bin/sh
WTTR=$(curl -s wttr.in/bydgoszcz) && \
exec io.elementary.terminal -e "echo $WTTR"
solve the problem?

ssh does not return even after execution

The following ssh command does not return to terminal. It hangs though the execution is completed. The execution hangs after echo hi command.
ssh user#testserver "echo hello;source .profile;source .bash_profile;/apps/myapp/deploytools/ciInstallAndRun.sh; echo hi"
Output
hello
<outoutfrom remote script"
hi
ciInstallAndRun.sh
echo 'starting'
cd /apps/myapp/current
./tctl kill
cd /apps/myapp
mv myapp_v1.0 "myapp_v1.0_`date '+%Y%m%d%H%M'`"
unzip -o /apps/myapp/myappdist-bin.zip
java -classpath .:/apps/myapp/deploytools/cleanup.jar se.telenor.project.cleanup.Cleanup /apps/myapp myapp_v1.0_ 3
cd /apps/myapp/myapp_v1.0
echo 'Done with deploy'
chmod -R 775 *
echo 'Done'
./tctl start test
Source OS: Redhat
Dest Os: Solaris 10 8/07
Any idea to fix this.
Any idea to fix this.
Your installation script has spawned a child process.
Add a ps -f or ptree $$ command before echo hi. You'll see a child process or multiple child processes spawned by your install script.
To stop the SSH command from hanging, you need to detach such child process(es) from your terminal's input/output. You can sedirect your script's output to a file - both stdout and stderr with > /some/output/file 2>&1, and also redirect its input with < /dev/null.
Or you can use the nohup command.
You haven't provided an MCVE, as others have noted, but this is likely the problem command in you install script, since your question implies that you see the expected output from your install script:
./tctl start test
You probably would do better to replace it with something like:
./tctl start test </dev/null >/some/log/file/path.log 2>&1

Run a script in the same shell(bash)

My problem is specific to the running of SPECCPU2006(a benchmark suite).
After I installed the benchmark, I can invoke a command called "specinvoke" in terminal to run a specific benchmark. I have another script, where part of the codes are like following:
cd (specific benchmark directory)
specinvoke &
pid=$!
My goal is to get the PID of the running task. However, by doing what is shown above, what I got is the PID for the "specinvoke" shell command and the real running task will have another PID.
However, by running specinvoke -n ,the real code running in the specinvoke shell will be output to the stdout. For example, for one benchmark,it's like this:
# specinvoke r6392
# Invoked as: specinvoke -n
# timer ticks over every 1000 ns
# Use another -n on the command line to see chdir commands and env dump
# Starting run for copy #0
../run_base_ref_gcc43-64bit.0000/milc_base.gcc43-64bit < su3imp.in > su3imp.out 2>> su3imp.err
Inside it it's running a binary.The code will be different from benchmark to benchmark(by invoking under different benchmark directory). And because "specinvoke" is installed and not just a script, I can not use "source specinvoke".
So is there any clue? Is there any way to directly invoke the shell command in the same shell(have same PID) or maybe I should dump the specinvoke -n and run the dumped materials?
You can still do something like:
cd (specific benchmark directory)
specinvoke &
pid=$(pgrep milc_base.gcc43-64bit)
If there are several invocation of the milc_base.gcc43-64bit binary, you can still use
pid=$(pgrep -n milc_base.gcc43-64bit)
Which according to the man page:
-n
Select only the newest (most recently started) of the matching
processes
when the process is a direct child of the subshell:
ps -o pid= -C=milc_base.gcc43-64bit --ppid $!
when not a direct child, you could get the info from pstree:
pstree -p $! | grep -o 'milc_base.gcc43-64bit(.*)'
output from above (PID is in brackets): milc_base.gcc43-64bit(9837)

Run a shell script in new terminal from current terminal

How do you run a shell script in a new terminal in Linux from a terminal like "start test.bat" in Windows, also it should be working in the console mode.
Here's a simple example to get you started:
To write a shell script, do this on your command prompt:
echo -e '#!/bin/sh\n echo "hello world"' > abc.sh
This writes:
#!/bin/sh
echo "hello world"
To a file called abc.sh
Next, you want to set it to executable by:
chmod +x abc.sh
Now, you can run it by:
./abc.sh
And you should see:
hello world
On your terminal.
To run it in a new terminal, you can do:
gnome-terminal -x ./abc.sh
or, if it's xterm:
xterm -e ./abc.sh
Here's a list of different terminal emulators.
Alternatively, you just run it in your current terminal, but background it instead by:
./abc.sh &
I came here wanting to figure out how to make a script spawn a terminal and run it self in it, so for those who want to do that I figured out this solution:
if [ ! -t 0 ]; then # script is executed outside the terminal?
# execute the script inside a terminal window with same arguments
x-terminal-emulator -e "$0" "$#"
# and abort running the rest of it
exit 0
fi
For gnome try this.
Replace ls with the command you want to run
gnome-terminal -x sh -c "ls|less"
I hope this is what you want
As of January 2020, the -e and -x option in gnome-terminal still run properly but throw out the following warnings:
For -e:
# Option “-e” is deprecated and might be removed in a later version
of gnome-terminal.
# Use “-- ” to terminate the options and put the command line to
execute after it.
For -x:
# Option “-x” is deprecated and might be removed in a later version
of gnome-terminal.
# Use “-- ” to terminate the options and put the command line to
execute after it.
Based on that information above, I confirmed that you can run the following two commands without receiving any warning messages:
gnome-terminal -- /bin/sh -c '<your command>'
gnome-terminal -- ./<your script>.sh
I hope this helps anyone else presently having this issue :)

Resources