Shell script does not exit to the prompt - linux

I have a shell script ws_appl_process that stop/start WebSphere servers:
#!/bin/sh
# ------------------------------------
# WebSphere Application Server process
# ------------------------------------
# PLEASE NOTE: This script assumes no spaces in the server names
# Finally, alter $APPSERVERS if server1 is required to start
PROF_HOME="/opt/WebSphere/AppServer855/profiles/xxxxxx"
## set colors
ec=`tput setaf 1` # error color
rc=`tput sgr 0` # reset color to default
if [ ! -d $PROF_HOME ];then
echo " "
echo "${ec}WARNING:${rc} unable to locate directory $PROF_HOME! No action taken."
echo " "
else
. $PROF_HOME/bin/setupCmdLine.sh
SERVERDIR=$PROF_HOME/config/cells/$WAS_CELL/nodes/$WAS_NODE/servers
APPSERVERS=`ls $SERVERDIR | egrep -v "jmsserver|nodeagent|web$"`
case "$1" in
'start')
# delay start by 30 seconds to let OS 'calm down' on startup
sleep 30
# start jmmserver first, if applicable
if [ -f $SERVERDIR/jmsserver/server.xml ]; then
$PROF_HOME/bin/startServer.sh jmsserver
fi
# start all servers found in config directory
for i in $APPSERVERS;do
$PROF_HOME/bin/startServer.sh $i &
sleep 1
done
;;
'stop')
for i in $APPSERVERS;do
$PROF_HOME/bin/stopServer.sh $i &
done
if [ -f $SERVERDIR/jmsserver/server.xml ]; then
$PROF_HOME/bin/stopServer.sh jmsserver
fi
;;
*)
echo "Usage: $0 { start | stop }"
exit 1
esac
fi
exit $?
Running this script
./ws_appl_process stop
will do what is intended, e.g. stop or start.
However, the script does NOT return to the prompt e.g. user#server:~>.
I have to manually hit the <RETURN> or <ENTER> key to get to the prompt.
I have tried to modify the last command
exit $?
to
exit 0
or
exit $?
exit 0
with no luck.
I need the script to return automatically to the prompt. The reason is that I am automating the monitor of the servers, and eventually bring them back, i.e.
./ws_appl_process start
The OS:
Linux xxxxxx 3.0.101-108.101-default #1 SMP Tue Aug 13 08:31:17 UTC 2019 (d0a7b7a) x86_64 x86_64 x86_64 GNU/Linux
The shell:
GNU bash, version 3.2.57(2)-release (x86_64-suse-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.
How can I force the script back to the prompt?
Appreciate any comments.

Related

Start an Electron app at boot on Raspberry Pi 3 with yocto

I built an image with X11 using yocto for a Raspberry Pi 3 and a touchscreen. I can start my app built with Electron (chromium) by running commands manually in a serial session:
export DISPLAY=:0
/usr/lib/node/electron/dist/electron --no-sandbox /home/root/app
I though to use an init.d script to do it automatically at startup but I'd like to do it the proper way. I tried to create an .Xsession file in my user directory with the commands above but it doesn't work and I don't know if I can get logs of what happened.
According to this wiki, there is a lot of steps at X11 startup. Currently, I only see a Terminal (from Matchbox I guess) and a mouse cursor.
What's the "standard" way to start an app with the system and is there a way to remove the cursor for a touchscreen?
Edit
Here is the content of my /etc/X11 directory:
Xsession
Xsession.d/
xinit/
xorg.conf
Xsession:
#!/bin/sh
if [ -x /usr/bin/dbus-launch ]; then
# As this is the X session script, always start a new DBus session.
eval `dbus-launch --sh-syntax --exit-with-session </dev/null`
echo "D-BUS per-session daemon address is: $DBUS_SESSION_BUS_ADDRESS"
fi
. /etc/profile
if [ -f $HOME/.profile ]; then
. $HOME/.profile
fi
SYSSESSIONDIR=/etc/X11/Xsession.d
export CLUTTER_DISABLE_MIPMAPPED_TEXT=1
for SESSIONFILE in $SYSSESSIONDIR/*; do
set +e
case "$SESSIONFILE" in
*.sh)
. "$SESSIONFILE"
;;
*.shbg)
"$SESSIONFILE" &
;;
*~)
# Ignore backup files
;;
*)
"$SESSIONFILE"
;;
esac
set -e
done
exit 0
xorg.conf: empty.
Xsession.d/:
13xdgbasedirs.sh
30xinput_calibrate.sh
89xdgautostart.sh
90XWindowManager.sh
89xdgautostart.sh:
XDGAUTOSTART=/etc/xdg/autostart
if [ -d $XDGAUTOSTART ]; then
for SCRIPT in $XDGAUTOSTART/*; do
CMD=`grep ^Exec= $SCRIPT | cut -d '=' -f 2`
$CMD &
done
fi
90XWindowManager.sh:
if [ -x $HOME/.Xsession ]; then
exec $HOME/.Xsession
elif [ -x /usr/bin/x-session-manager ]; then
exec /usr/bin/x-session-manager
else
exec /usr/bin/x-window-manager
fi
There is also a file /etc/xserver-nodm/Xserver:
#!/bin/sh
# This script is only needed to make sure /etc/X11/xserver-common
# can affect XSERVER, ARGS & DPI: otherwise systemd could just use
# /etc/default/xserver-nodm as EnvironmentFile and sysvinit could just
# source the same file
. /etc/profile
# load default values for XSERVER, ARGS, DISPLAY...
. /etc/default/xserver-nodm
# Allow xserver-common to override ARGS, XSERVER, DPI
if [ -e /etc/X11/xserver-common ] ; then
. /etc/X11/xserver-common
if [ ! -e $XSERVER ] ; then
XSERVER=$(which $XSERVER)
fi
fi
if [ -n "$DPI" ] ; then
ARGS="$ARGS -dpi $DPI"
fi
exec xinit /etc/X11/Xsession -- $XSERVER $DISPLAY $ARGS $*
and a file /etc/rc5.d/S09xserver-nodm:
#!/bin/sh
#
### BEGIN INIT INFO
# Provides: xserver
# Required-Start: $local_fs $remote_fs dbus
# Required-Stop: $local_fs $remote_fs
# Default-Start: 5
# Default-Stop: 0 1 2 3 6
### END INIT INFO
killproc() { # kill the named process(es)
pid=`/bin/pidof $1`
[ "$pid" != "" ] && kill $pid
}
read CMDLINE < /proc/cmdline
for x in $CMDLINE; do
case $x in
x11=false)
echo "X Server disabled"
exit 0;
;;
esac
done
case "$1" in
start)
. /etc/profile
#default for USER
. /etc/default/xserver-nodm
echo "Starting Xserver"
if [ "$USER" != "root" ]; then
# setting for rootless X
chmod o+w /var/log
chmod g+r /dev/tty[0-3]
# hidraw device is probably needed
if [ -e /dev/hidraw0 ]; then
chmod o+rw /dev/hidraw*
fi
fi
# Using su rather than sudo as latest 1.8.1 cause failure [YOCTO #1211]
su -l -c '/etc/xserver-nodm/Xserver &' $USER
# Wait for the desktop to say its finished loading
# before loading the rest of the system
# dbus-wait org.matchbox_project.desktop Loaded
;;
stop)
echo "Stopping XServer"
killproc xinit
sleep 1
chvt 1 &
;;
restart)
$0 stop
$0 start
;;
*)
echo "usage: $0 { start | stop | restart }"
;;
esac
exit 0
The correct way to define a complete X session depends on your session manager: on Yocto that is often matchbox-session or mini-x-session. From your description I'd guess you're using mini-x-session (it happens to start a terminal and a window-manager if session file is not found).
Quoting mini-x-session:
if [ -e $HOME/.mini_x/session ]
then
exec $HOME/.mini_x/session
fi
if [ -e /etc/mini_x/session ]
then
exec /etc/mini_x/session
fi
So adding a /etc/mini_x/session script should work.
By the way, in your session file you may also want to start a window manager (X can do weird things without one):
your-app-here &
exec matchbox-window-manager

How to close firefox at a given time in linux?

The challenge is to be able to close firefox at a given time, to protect a person from its own "internet addiction" and ensure some rest during the night.
In this case, my partner asked to shut firefox down at 22h00, as she was staying up at night and then the next day being tired.
And when she happened to want to open firefox after 22h00, close it automatically after 15 minutes from when she opened it.
EDIT
I've written this question with an answer in place already where I created a shell script and then integrated with linux file.
There in an error on the code thatif time is before 22h00, it still is adding 15 minutes.
now=$(date +'%R')
KILL_DATE=$(date -d "22:00 today" +'%R')
if [ "$now" > "$KILL_DATE" ]; then
KILL_DATE=$(date -d "$now today + 15 minutes" +'%R')
fi
exec echo "pkill -f firefox" | at $KILL_DATE
exec $MOZ_PROGRAM "$#"
The solution I found for this was to:
replicate firefox file on /usr/bin/ to firefox_daytime
update the lines where firefox is loaded and use the "at" command to execute the background killing task at the specified time.
This was chosen because usually she opens firefox from the shortcuts on her "start menu".
This was only tested using openSuse.
specifically, the code for achieving this was:
now=$(date +'%R')
kill_date=$(date -d "22:00 today" +'%R')
if [ $now -gt $kill_date ]; then
kill_date=$(date -d "$now today + 15 minutes" +'%R')
fi
exec echo "pkill -f firefox" | at $kill_date
exec $MOZ_PROGRAM "$#"
Which can be found on the last lines of the new file.
/usr/bin/firefox_daytime
#!/bin/sh
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org Code.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1998
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Wolfgang Rosenauer <wolfgang.rosenauer#suse.de>
# <wr#rosenauer.org>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
##
## Usage:
##
## $ mozilla [args]
##
## This script is meant to run a mozilla program from the mozilla
## rpm installation.
##
## The script will setup all the environment voodoo needed to make
## mozilla work.
cmdname=`basename $0`
##
## Variables
##
MOZ_DIST_BIN="/usr"
MOZ_DIST_LIB="/usr/lib64/firefox"
MOZ_APPNAME="firefox"
MOZ_PROGRAM="$MOZ_DIST_LIB/$MOZ_APPNAME"
MOZ_APP_LAUNCHER="$MOZ_DIST_LIB/$MOZ_APPNAME.sh"
if [ "$0" = "$MOZ_APP_LAUNCHER" ]; then
[ -h "/usr/bin/$MOZ_APPNAME" ] && \
_link=$(readlink -f "/usr/bin/$MOZ_APPNAME")
if [ "$_link" = "$MOZ_APP_LAUNCHER" ]; then
export MOZ_APP_LAUNCHER="/usr/bin/$MOZ_APPNAME"
fi
else
export MOZ_APP_LAUNCHER="/usr/bin/$MOZ_APPNAME"
fi
mozilla_lib=`file $MOZ_PROGRAM`
LIB=lib
echo $mozilla_lib | grep -q -E 'ELF.64-bit.*(x86-64|S/390|PowerPC)' && LIB=lib64
BROWSER_PLUGIN_DIR=/usr/$LIB/browser-plugins
if [ ! -d $BROWSER_PLUGIN_DIR ]; then
BROWSER_PLUGIN_DIR=/opt/netscape/plugins
fi
MOZILLA_FIVE_HOME="$MOZ_DIST_LIB"
export MOZILLA_FIVE_HOME
LD_LIBRARY_PATH=$MOZ_DIST_LIB${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
export LD_LIBRARY_PATH
# needed for SUN Java under Xorg >= 7.2
export LIBXCB_ALLOW_SLOPPY_LOCK=1
##
if [ -z "$MOZ_PLUGIN_PATH" ]; then
export MOZ_PLUGIN_PATH=$BROWSER_PLUGIN_DIR
else
# make sure that BROWSER_PLUGIN_DIR is in MOZ_PLUGIN_PATH
echo "$MOZ_PLUGIN_PATH" | grep "$BROWSER_PLUGIN_DIR" 2>&1 >/dev/null
_retval=$?
if [ ${_retval} -ne 0 ]; then
export MOZ_PLUGIN_PATH=$MOZ_PLUGIN_PATH:$BROWSER_PLUGIN_DIR
fi
fi
# disable Gnome crash dialog (doesn't make sense anyway)
export GNOME_DISABLE_CRASH_DIALOG=1
moz_debug=0
script_args=""
pass_arg_count=0
while [ $# -gt $pass_arg_count ]
do
case "$1" in
-d | --debugger)
moz_debugger=$2;
if [ "${moz_debugger}" != "" ]; then
shift 2
moz_debug=1
else
echo "-d requires an argument"
exit 1
fi
;;
*)
# Move the unrecognized argument to the end of the list.
arg="$1"
shift
set -- "$#" "$arg"
pass_arg_count=`expr $pass_arg_count + 1`
;;
esac
done
if [ $moz_debug -eq 1 ]; then
tmpfile=`mktemp /tmp/mozargs.XXXXXX` || { echo "Cannot create temporary file" >&2; exit 1; }
trap " [ -f \"$tmpfile\" ] && /bin/rm -f -- \"$tmpfile\"" 0 1 2 3 13 15
echo "set args ${1+"$#"}" > $tmpfile
echo "run" >> $tmpfile
echo "$moz_debugger $MOZ_PROGRAM -x $tmpfile"
exec $moz_debugger "$MOZ_PROGRAM" -x $tmpfile
else
now=$(date +'%R')
kill_date=$(date -d "22:00 today" +'%R')
if [ $now -gt $kill_date ]; then
kill_date=$(date -d "$now today + 15 minutes" +'%R')
fi
exec echo "pkill -f firefox" | at $kill_date
exec $MOZ_PROGRAM "$#"
fi

can shell script make itself run in background after running some steps?

I have BBB based custom Embedded Linux based board with busybox shell(ash)
I have a situation where my script must run in background with following condition
There must only one instance of the script.
wrapper script need to know if script started successfully in background or not.
There is another wrapper script which starts and stops my script, wrapper script is as mentioned below.
#!/bin/sh
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
readonly TEST_SCRIPT_PATH="/home/testscript.sh"
readonly TEST_SCRIPT_LOCK_PATH="/var/run/${TEST_SCRIPT_PATH##*/}.lock"
start_test_script()
{
local pid_of_testscript=0
local status=0
#Run test script in background
"${TEST_SCRIPT_PATH}" &
#---------Now When this point is hit, lock file must be created.-----
if [ -f "${TEST_SCRIPT_LOCK_PATH}" ];then
pid_of_testscript=$(head -n1 ${TEST_SCRIPT_LOCK_PATH})
if [ -n "${pid_of_testscript}" ];then
kill -0 ${pid_of_testscript} &> /dev/null || status="${?}"
if [ ${status} -ne 0 ];then
echo "Error starting testscript"
else
echo "testscript start successfully"
fi
else
echo "Error starting testscript.sh"
fi
fi
}
stop_test_script()
{
local pid_of_testscript=0
local status=0
if [ -f "${TEST_SCRIPT_LOCK_PATH}" ];then
pid_of_testscript=$(head -n1 ${TEST_SCRIPT_LOCK_PATH})
if [ -n "${pid_of_testscript}" ];then
kill -0 ${pid_of_testscript} &> /dev/null || status="${?}"
if [ ${status} -ne 0 ];then
echo "testscript not running"
rm "${TEST_SCRIPT_LOCK_PATH}"
else
#send SIGTERM signal
kill -SIGTERM "${pid_of_testscript}"
fi
fi
fi
}
#Script starts from here.
case ${1} in
'start')
start_test_script
;;
'stop')
stop_test_script
;;
*)
echo "Usage: ${0} [start|stop]"
exit 1
;;
esac
Now actual script "testscript.sh" looks something like this,
#!/bin/sh
#Filename : testscript.sh
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
set -eu
LOCK_FILE="/var/run/${0##*/}.lock"
FLOCK_CMD="/bin/flock"
FLOCK_ID=200
eval "exec ${FLOCK_ID}>>${LOCK_FILE}"
"${FLOCK_CMD}" -n "${FLOCK_ID}" || exit 0
echo "${$}" > "${LOCK_FILE}"
# >>>>>>>>>>-----Now run the code in background---<<<<<<
handle_sigterm()
{
# cleanup
"${FLOCK_CMD}" -u "${FLOCK_ID}"
if [ -f "${LOCK_FILE}" ];then
rm "${LOCK_FILE}"
fi
}
trap handle_sigterm SIGTERM
while true
do
echo "do something"
sleep 10
done
Now in above script you can see "---Now run the code in background--" at that point I am sure that either lock file is successfully created or instance of this script is already running. So Then I can safely run other code in background and wrapper script can check for lockfile and find out if the process mentioned in the lock file is running or not.
can shellscript itself make it to run in background ?
if not is there a better way to meet all the conditions ?
I think you can look into job control built-in, specifically bg.
Job Control Commands
When processes say they background themselves, what they actually do is fork and exit the parent. You can do the same by running whichever commands, functions or statements you want with & and then exiting.
#!/bin/sh
echo "This runs in the foreground"
sleep 3
while true
do
sleep 10
echo "doing background things"
done &

How to see JBOSS has started/stopped from commandline

Is there some linux/jboss command I can use in a script to see if jboss started.
I have to start up a couple in a specified order and one of the jbosses must
be started before the others can be started up.
/T
Refer this link ,With the following command you can try to read the server "Started" attribute
twiddle get "jboss.system:type=Server" Started
Started=true
On Fedora 19, you can install the jboss-as package, which comes with a nice startup script, and you can check the status just like any other daemon: systemctl status jboss-as
Similarly for Fedora 20 and Wildfly: systemctl status wildfly .
Here is a script I used:
#!/bin/bash
CHECK_TIMEOUT=$1;
if [[ $1 =~ ^[0-9]+$ ]]; then
echo "Checking if JBoss is running with timeout of $1 s.";
else
echo "Checking if JBoss is running with default timeout of 60 s.";
CHECK_TIMEOUT=60;
fi
while [[ $CHECK_TIMEOUT -ne 0 ]]
do
sleep 1;
JBOSS_STATE=`~/jboss/bin/jboss-cli.sh 'connect,:read-attribute(name=server-state),q' | grep result`;
if [[ -z $JBOSS_STATE ]]; then
JBOSS_STATE="stopped";
else
JBOSS_STATE=`echo "$JBOSS_STATE" | tr -s \" " " | cut -d ' ' -f 4`;
fi
echo "JBoss is $JBOSS_STATE";
if [[ $JBOSS_STATE == "running" ]]; then
exit 0;
fi
((CHECK_TIMEOUT-=1));
done
exit 1;

Call to daemon in a /etc/init.d script is blocking, not running in background

I have a Perl script that I want to daemonize. Basically this perl script will read a directory every 30 seconds, read the files that it finds and then process the data. To keep it simple here consider the following Perl script (called synpipe_server, there is a symbolic link of this script in /usr/sbin/) :
#!/usr/bin/perl
use strict;
use warnings;
my $continue = 1;
$SIG{'TERM'} = sub { $continue = 0; print "Caught TERM signal\n"; };
$SIG{'INT'} = sub { $continue = 0; print "Caught INT signal\n"; };
my $i = 0;
while ($continue) {
#do stuff
print "Hello, I am running " . ++$i . "\n";
sleep 3;
}
So this script basically prints something every 3 seconds.
Then, as I want to daemonize this script, I've also put this bash script (also called synpipe_server) in /etc/init.d/ :
#!/bin/bash
# synpipe_server : This starts and stops synpipe_server
#
# chkconfig: 12345 12 88
# description: Monitors all production pipelines
# processname: synpipe_server
# pidfile: /var/run/synpipe_server.pid
# Source function library.
. /etc/rc.d/init.d/functions
pname="synpipe_server"
exe="/usr/sbin/synpipe_server"
pidfile="/var/run/${pname}.pid"
lockfile="/var/lock/subsys/${pname}"
[ -x $exe ] || exit 0
RETVAL=0
start() {
echo -n "Starting $pname : "
daemon ${exe}
RETVAL=$?
PID=$!
echo
[ $RETVAL -eq 0 ] && touch ${lockfile}
echo $PID > ${pidfile}
}
stop() {
echo -n "Shutting down $pname : "
killproc ${exe}
RETVAL=$?
echo
if [ $RETVAL -eq 0 ]; then
rm -f ${lockfile}
rm -f ${pidfile}
fi
}
restart() {
echo -n "Restarting $pname : "
stop
sleep 2
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status ${pname}
;;
restart)
restart
;;
*)
echo "Usage: $0 {start|stop|status|restart}"
;; esac
exit 0
So, (if I have well understood the doc for daemon) the Perl script should run in the background and the output should be redirected to /dev/null if I execute :
service synpipe_server start
But here is what I get instead :
[root#master init.d]# service synpipe_server start
Starting synpipe_server : Hello, I am running 1
Hello, I am running 2
Hello, I am running 3
Hello, I am running 4
Caught INT signal
[ OK ]
[root#master init.d]#
So it starts the Perl script but runs it without detaching it from the current terminal session, and I can see the output printed in my console ... which is not really what I was expecting. Moreover, the PID file is empty (or with a line feed only, no pid returned by daemon).
Does anyone have any idea of what I am doing wrong ?
EDIT : maybe I should say that I am on a Red Hat machine.
Scientific Linux SL release 5.4 (Boron)
Thanks,
Tony
I finally re-wrote the start function in the bash init script, and I am not using daemon anymore.
start() {
echo -n "Starting $pname : "
#daemon ${exe} # Not working ...
if [ -s ${pidfile} ]; then
RETVAL=1
echo -n "Already running !" && warning
echo
else
nohup ${exe} >/dev/null 2>&1 &
RETVAL=$?
PID=$!
[ $RETVAL -eq 0 ] && touch ${lockfile} && success || failure
echo
echo $PID > ${pidfile}
fi
}
I check that the pid file is not existing already (if so, just write a warning). If not, I use
nohup ${exe} >/dev/null 2>&1 &
to start the script.
I don't know if it is safe this way (?) but it works.
The proper way to daemonize a process is have it detach from the terminal by itself. This is how most larger software suites do it, for instance, apache.
The rationale behind daemon not doing what you would expect from its name, and how to make a unix process detach into the background, can be found here in section 1.7 How do I get my program to act like a daemon?
Simply invoking a program in the background isn't really adequate for
these long-running programs; that does not correctly detach the
process from the terminal session that started it. Also, the
conventional way of starting daemons is simply to issue the command
manually or from an rc script; the daemon is expected to put itself
into the background.
For further reading on this topic: What's the difference between nohup and a daemon?
According to man daemon correct syntax is
daemon [options] -- [command] [command args]
Your init script startup should run something like:
daemon --pidfile ${pidfile} -- ${exe}
As said here, it seems that the process needs to be sent to the background using &.
Daemon don’t do it for you.

Resources