Question about ssh remote script execution - ssh

There are two scripts on HostB
# loop.sh
while true; do
date
sleep 2
done
and
# loop12.sh
optv=$1
while true; do
case $optv in
2)
echo "from stderr" >&2
date >&2
;;
*)
echo "from stdout"
date
;;
esac
sleep 2
done
I run ssh HostB './loop.sh &' on HostA, the Terminal prints the date every 2 seconds.
When I press Ctrl + c to stopssh HostB running on HostA, and check the process with ps -ef | grep loop on HostB, the process loop.sh is still there.
I run ssh HostB './loop12.sh &' on HostA, the Terminal prints the date every 2 seconds, too.
But when I press Ctrl + c to stopssh HostB running on HostA, and check the process with ps -ef | grep loop12 on HostB, the process loop12.sh is gone.
I just wonder Why the scripts are similar but they have different phenomenon?

Related

How to ask a remote server over SSH to run a background job?

I'm trying to start a long-running process on a remote server, over SSH:
$ echo Hello | ssh user#host "cat > /tmp/foo.txt; sleep 100 &"
Here, sleep 100 is a simulation of my long-running process. I want this command to exit instantly, but it waits for 100 seconds. Important to mention that I need the job to receive an input from me (Hello in the example above).
Server:
$ sshd -?
OpenSSH_8.2p1 Ubuntu-4ubuntu0.5, OpenSSL 1.1.1f 31 Mar 2020
Saying "I want this command to exit instantly" is incompatible with "long-running". Perhaps you mean that you want the long-running command to run in the background.
If output is not immediately needed locally (ie. it can be retrieved by another ssh in future), then nohup is simple:
echo hello |
ssh user#host '
cat >/tmp/foo.txt;
nohup </dev/null >cmd.out 2>cmd.err cmd &
'
If output must be received locally as the command runs, you can background ssh itself using -f:
echo hello |
ssh -f user#host '
cat >/tmp/foo.txt;
cmd
' >cmd.out 2>cmd.err

Using tail to monitor an active logging file

I'm running multiple 'shred' commands on multiple hard drives in a workstation. The 'shred' commands are all run in the background in order to run the commands concurrently. The output of each 'shred' is redirected to a text file, and I also have the output directed to the terminal as well. I'm using tail to monitor the log file for errors, and halt the script if any are encountered. If there are no errors, the script should simply continue on to conclusion. When I test it by forcing a drive failure (disconnecting a drive), it detects the I/O errors and the script halts as expected. The problem I'm having is that when there are NO errors, I cannot get 'tail' to terminate once the 'shred' commands have completed, and the script just hangs at that point. Since I put the 'tail' command in the 'while' loop below, I would have thought that 'tail' would continue to run as long as the 'shred' processes were running, but would then halt after the 'shred' processes stopped, thus ending the 'while' loop. But that hasn't been the case. The script still hangs even after the 'shred' processes have ended. If I go to another terminal window while the script is "hangiing," and kill the 'tail' process, the script continues as normal. Any ideas how to get the 'tail' process to end when the 'shred' processes are gone?
My code:
shred -n 3 -vz /dev/sda 2>&1 | tee -a logfile &
shred -n 3 -vz /dev/sdb 2>&1 | tee -a logfile &
shred -n 3 -vz /dev/sdc 2>&1 | tee -a logfile &
pids=$(pgrep shred)
while kill -0 $pids 2> /dev/null; do
tail -qn0 -f logfile | \
read LINE
echo "$LINE" | grep -q "error"
if [ $? = 0 ]; then
killall shred > /dev/null 2>&1
echo "Error encountered. Halting."
exit
fi
done
wait $pids
There is other code after the 'wait' that does other stuff, but this is where the script is hanging
Not directly related to the question, but you can use Daggy - Data Aggregation Utility
In this case, all subprocesses will be end with main daggy process.

Monit wait for a file to start a process?

Basically the monit to start a process "CAD" when a file "product_id" is ready. My config is as below:
check file product_id with path /etc/platform/product_id
if does not exist then alert
check process cad with pidfile /var/run/cad.pid
depends on product_id
start = "/bin/sh -c 'cd /home/root/cad/scripts;./run-cad.sh 2>&1 | logger -t CAD'" with timeout 120 seconds
stop = "/bin/sh -c 'cd /home/root/cad/scripts;./stop-cad.sh 2>&1 | logger -t CAD'"
I’m expecting “monit” to call “start” until the file is available. But it seems it restarted the process (stop and start) every cycle.
Is there anything configured wrong here?
Appreciate any help.
The reason it's restarting every cycle is because the product_id file is not ready. Anything that depends on product_id will be restarted if the check fails.
I would suggest writing a script that checks for the existence of product_id and starts CAD if it's there. You could then run this script from a "check program" block in monit.
This is how I do it:
check program ThisIsMyProgram with path "/home/user/program_check.sh"
every 30 cycles
if status == 1 then alert
This will run the shell script, and error if status = 1.
Shell script:
#!/bin/bash
FILE=/path/to/file/that/needs/to/exist.json
PID=$(sudo pidof ThisIsMyProgram)
if [ -s $FILE ]; then
if [ ! -z "$PID" ];then
exit 0
else
sudo service thisismyprogram start 2>&1 >> /dev/null
exit 1
fi
else
exit 0
fi
Shell script checks if file exist, if it does it will start process and keep it running.

cannot kill process in FreeBSD

I have a script in FreeBSD 10.1 release, it's purpose is to monitor another process and keep the process alive.
When I try to kill itself, it always fail.
I try killall [name | pid]; pkill -9 [name]; service watchtas stop, none of them work.
Below is my script, please advise the solution.
#!/bin/sh
. /etc/rc.subr
prog="Thin-Agent WatchDog"
TAS_BIN="/etc/supermicro/tas-freebsd.x86_64"
TAS_LOG="/etc/supermicro/tas_system_crush.log"
monitor=1
name="watchtas"
rcvar=${name}_enable
command=/etc/rc.d/{$name}
start_cmd="watchdog"
stop_cmd="stop_watching"
load_rc_config $name
recover_tas() {
$TAS_BIN -agent start-service
RETVAl=$?
return $RETVAL
}
stop_watching() {
monitor=0
}
watchdog() {
while [ $monitor == 1 ]
do
tas_count=`ps -x | grep tas-freebsd.x86_64 | grep -v grep | wc -l | sed 's/ *//g'`
if [ $tas_count -eq 0 ]; then
timestamp=`date`
echo "[$timestamp]TAS shutdown unexpectedly, restarting TAS now..." >> $TAS_LOG
echo $?
recover_tas
else
sleep 10
fi
done
}
run_rc_command "$1"
Your start-up script fails in a couple of respects. service watchtas start does not return to the command line because the daemon process does not detach. service watchtas stop does not work as required because the variable monitor is local to the executing script.
I would separate the start-up script and the watchdog code into separate files and use daemon(8) to monitor the watchdog.
The /usr/local/etc/rc.d start-up script would look like this:
#!/bin/sh
. /etc/rc.subr
name="watchtas"
rcvar=${name}_enable
pidfile="/var/run/${name}.pid"
command="/usr/sbin/daemon"
command_args="-c -f -P ${pidfile} -r /usr/local/sbin/${name}"
load_rc_config $name
run_rc_command "$1"
The /usr/local/sbin/watchtas watchdog code would look something like this:
#!/bin/sh
TAS_BIN="/etc/supermicro/tas-freebsd.x86_64"
TAS_LOG="/etc/supermicro/tas_system_crush.log"
recover_tas() {
$TAS_BIN -agent start-service
RETVAl=$?
return $RETVAL
}
while true
do
tas_count=`ps -x | grep tas-freebsd.x86_64 | grep -v grep | wc -l | sed 's/ *//g'`
if [ $tas_count -eq 0 ]; then
timestamp=`date`
echo "[$timestamp]TAS shutdown unexpectedly, restarting TAS now..." >> $TAS_LOG
echo $?
recover_tas
else
sleep 10
fi
done
It seems you have a daemon watching a daemon watching a daemon.

Apache Ace as a Service

I am trying to setup/configure Apache ACE for the first time. It seems like I got everything running correctly but I would like to have ACE startup automatically when the Linux box starts. I created the init.d script below which does starts up ACE however it drops me in an OSGI console and when I leave the console ACE shuts down.
Is there a way to start ACE without having the OSGI console so I do not have to keep my session open to keep ACE running?
#! /bin/bash
BIN_DIR=/opt/ace-current/server-allinone
PATH=/bin:/usr/bin:/sbin:/usr/sbin
JAVA_HOME=/usr/lib/jvm/default-java
if [ `id -u` -ne 0 ]; then
echo "You need root privileges to run this script"
exit 1
fi
. /lib/lsb/init-functions
if [ -r /etc/default/rcS ]; then
. /etc/default/rcS
fi
case $1 in
start)
cd $BIN_DIR
java -Dorg.apache.ace.server=localhost:11868 -Dorg.osgi.service.http.port=11868 -Dorg.apache.ace.obr=localhost:11868 -jar server-allinone.jar
;;
stop)
pid=`ps aux | grep server-allinone | awk '{print $2}'`
kill -9 $pid
;;
restart)
$0 stop
$0 start
;;
esac
exit 0
java -Dgosh.args=--nointeractive -jar server-allinone.jar
Will disable the local shell.