According to the knoppix-halt file, it mention that
Please remove CD, close cdrom drive and hit return [2 minutes]
I look through the file so many times but still could not find the 2 minutes setting. I know that sleep X will sleep for X seconds while usleep X will sleep for microsecond. So, I went to look for sleep 120 and usleep 120000000 but did not find any.
So, can someone enlighten me why the message say 2 minutes but I could not find inside the script file?
#!/bin/busybox sh
# This script does:
# - Kill all processes
# - umount/sync filesystems (and freeing loopback files)
# - Eventually eject CD-Rom (autoeject turned on)
PATH=/sbin:/bin:/usr/bin:/usr/sbin:/usr/local/sbin:/usr/local/bin
export PATH
cd /
NORMAL="\033[0;39m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
MAGENTA="\033[1;35m"
CYAN="\033[1;36m"
WHITE="\033[1;37m"
GRAY="\033[1;38m"
[ -r /etc/default/locale ] && . /etc/default/locale
[ -r /etc/sysconfig/i18n ] && . /etc/sysconfig/i18n
case "$LANG" in
de*)
EJECTMSG="Bitte CD entfernen, Laufwerk schließen und Eingabetaste drücken [2 Minuten]"
COMPLETEMSG="Shutdown beendet."
;;
*)
EJECTMSG="Please remove CD, close cdrom drive and hit return [2 minutes]."
COMPLETEMSG="Shutdown complete."
;;
esac
# Read in boot parameters
read CMDLINE </proc/cmdline 2>/dev/null
echo 0 >/proc/sys/kernel/printk
PROGRESSBAR="/tmp/knoppix-halt.progress"
progress(){
local black="\033[0;0m \033[0m"
local p
local count=0
echo -n -e "\033[1mSystem Shutdown... \033[42;32m \033[0m"
type usleep >/dev/null 2>&1 && sleep="usleep 100000" || sleep="sleep 1"
[ -r "$PROGRESSBAR" ] && rm -f "$PROGRESSBAR" 2>/dev/null
touch "$PROGRESSBAR"
while [ -r "$PROGRESSBAR" ]; do
if [ "$count" -ge 55 ]; then
for p in "/" "-" "\\" "|"; do
echo -n -e "\b${p}"
$sleep
[ -r "$PROGRESSBAR" ] || break
done
else
echo -n -e "\b$black\b"
$sleep
fi
let count++
done
echo -e "\r\033[J\033[1m${COMPLETEMSG}\033[0m"
}
# Return 0 if there is active swap, but
# enough memory available to call swapoff, 1 otherwise.
checkswap(){
local free=0 buffers=0 cache=0 swaptotal=0 swapfree=0 info amount kb
while read info amount kb; do
case "$info" in
MemFree:) free="$amount";;
Buffers:) buffers="$amount";;
Cached:) cached="$amount";;
SwapTotal:) swaptotal="$amount";;
SwapFree:) swapfree="$amount";;
esac
done </proc/meminfo
avail="$((free + buffers + cached))"
swapused="$((swaptotal - swapfree))"
if [ "$swaptotal" -gt 0 -a "$avail" -gt "$swapused" ] >/dev/null 2>&1; then
return 0
else
return 1
fi
}
OMIT=""
for i in $(pidof ntfs-3g aufs aufsd fuse fuseblk cloop0 cloop1 cloop2 cloop3 cloop4 cloop5 cloop6 cloop7 klogd syslogd); do OMIT="$OMIT -o $i"; done 2>/dev/null
killall5 -15 $OMIT; sleep 2
case "$CMDLINE" in *nosound*|*noaudio*|*nostartsound*) true ;; *)
# Play sound if soundcard is alive and soundfile present
# (also giving running programs some more time to terminate)
[ -r /usr/share/sounds/shutdown.ogg -a -f /proc/asound/pcm ] && \
type -p ogg123 >/dev/null 2>&1 && \
{ ogg123 -q --audio-buffers 4096 /usr/share/sounds/shutdown.ogg 2>/dev/null & sleep 2; }
;;
esac
# Clean console i/o
exec >/dev/console 2>&1 </dev/console
stty sane
echo -n -e "\r\033[K"
# echo -e "\033[H\033[J"
# Start progress bar
[ -n "$DEBUG" ] || progress &
# Check which device is mounted as /mnt-system
system="$(awk '/ \/mnt-system /{print $1;exit 0}' /proc/mounts 2>/dev/null)"
# noprompt or noeject option?
NOPROMPT="yes"; NOEJECT="yes"
case "$CMDLINE" in
*noprompt*) ;;
*) # Check if we need to wait for /mnt-system to be ejected.
if [ -n "$system" ]; then
for cdrom in $(awk '/drive name:/{print $NF}' /proc/sys/dev/cdrom*/info 2>/dev/null); do
[ "$system" = "/dev/$cdrom" ] && { NOEJECT=""; NOPROMPT=""; break; }
done
fi
;;
esac
case "$CMDLINE" in *noeject*) NOEJECT="yes" ;; esac
DEBUG=""
case "$CMDLINE" in *\ debug\ *|*BOOT_IMAGE=debug*) DEBUG="yes" ;; esac
# turn off swap, then unmount file systems.
# should free ramdisk space first, check
if checkswap; then
swapoff -a >/dev/null 2>&1
fi
# Shut down network, if no nfs mounted
# Actually... Not needed.
# grep -q ' nfs' /proc/mounts || ifdown -a >/dev/null 2>&1
# Kill remaining processes
killall5 -9 $OMIT
# Turn on autoeject of CD-Roms
if [ -z "$NOEJECT" ]; then
for dev in /proc/sys/dev/cdrom*/lock; do [ -f "$dev" ] && echo 0 > "$dev"; done
for dev in /proc/sys/dev/cdrom*/autoeject; do [ -f "$dev" ] && echo 1 > "$dev"; done
fi
# Try to sync for 30 seconds max.
sync &
SYNCPID="$!"
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do
sleep 2
[ -d /proc/"$SYNCPID" ] || break
done
# Free modules
# Do we need to unload modules at all?
#
#while read module relax; do
# case "$module" in
# *eeepc*|*_laptop*) true ;; # Unloading eeepc_laptop disables WLAN in the BIOS. Why?
# *) rmmod "$module" ;;
# esac
#done </proc/modules >/dev/null 2>&1
# Remove all automatically added entries from /etc/fstab
sed -i -e "/^# Added by KNOPPIX/{N;d}" /etc/fstab
# Force sync, then umount.
tac /proc/mounts | while read d m f relax; do
[ -d "$d" ] || continue
case "$f" in tmpfs|proc|sysfs|devpts|usbfs|aufs) ;; *)
case "$f" in rootfs|nfs*) ;; *) blockdev --flushbufs "$d" 2>/dev/null; umount -l "$m" 2>/dev/null ;; esac
case "$d" in /dev/mapper/*) /sbin/dmsetup --force remove "$d" 2>/dev/null ;; esac
;;
esac
done
# We have to use /bin/umount here, since busybox umount does not accept -t no*
# /bin/umount -t notmpfs,noproc,nosysfs,nousbfs,norootfs,noaufs,nonfs -adrf 2>/dev/null
# Free loopback devices which may have been used but not mounted.
for i in /dev/loop* /dev/loop/*; do [ -b "$i" ] && losetup -d "$i" 2>/dev/null; done
# End progress bar
[ -f "$PROGRESSBAR" ] && { rm -f "$PROGRESSBAR" 2>/dev/null; sleep 1; }
sleep 1
echo ""
# Mount boot medium read-only
umount -r /mnt-system 2>/dev/null
# And finally, umount
umount -l /mnt-system 2>/dev/null
# (Harddisk-installation only): mount / read-only
umount -r / 2>/dev/null
# Enable sysrq feature (just in case someone has turned it off)
# echo -n -e '\033[s\033[8m' # No output, save cursor position
echo 1 > /proc/sys/kernel/sysrq
echo s > /proc/sysrq-trigger 2>/dev/null & # emergency sync
sleep 1
echo u > /proc/sysrq-trigger 2>/dev/null & # emergency remount-ro
sleep 1
# echo -n -e '\033[28m\033[u' # re-enable output, restore cursor position
# pre-load poweroff+halt+eject if not included in this shell
poweroff --help >/dev/null 2>&1
reboot --help >/dev/null 2>&1
eject --help >/dev/null 2>&1
if [ -z "$NOEJECT" ]; then
( eject -s $system >/dev/null 2>&1 || eject $system >/dev/null 2>&1 & )
if [ -z "$NOPROMPT" ]; then
echo -n -e "${CYAN}${EJECTMSG}${NORMAL} "
read -t 120 a
fi
fi
case "$0" in
*halt|*poweroff) { poweroff -f 2>/dev/null & sleep 8; } || echo o > /proc/sysrq-trigger 2>/dev/null ;;
*) { reboot -f 2>/dev/null & sleep 8; } || echo b > /proc/sysrq-trigger 2>/dev/null ;;
esac
# Should never be reached.
sleep 2
echo -n -e "\033[1mYou can now turn off your computer.\033[0m"
halt -f
sleep 1337
At the bottom it says:
echo -n -e "${CYAN}${EJECTMSG}${NORMAL} "
read -t 120 a
This writes the message, and then waits up to 120 seconds for you to press return.
Related
I am trying to source an auto-completion script as a non-root user but receive a 'Bad Substitution' error message.
I am able to source it as root though.
On a other server I am able to source the script as non-root user.
I am guessing it is not a permission issue since I receive the same error trying to source a copy of the script with full permissions.
I have tried to echo all the environment variables used in the script, no issue there.
As the auto-completion script is packaged with the software I use I would rather not modify it.
Anyone would have a hint on what could be missing to the user so I can source the script from it ?
Thanks in advance for any idea!
Edit1:
ps output:
PID TTY TIME CMD
3261 pts/0 00:00:00 bash
73620 pts/0 00:00:00 ps
Error only as non-root user:
/opt/splunk/share/splunk/cli-command-completion.sh: 7: /opt/splunk/share/splunk/cli-command-completion.sh: Bad substitution
Script:
# Vainstein K 12aug2013
# # # Check a few prereqs.
feature='"splunk <verb> <object>" tab-completion'
[ `basename $SHELL` != 'bash' ] && echo "Sorry, $feature is only for bash" >&2 && return 11
[ ${BASH_VERSINFO[0]} -lt 4 ] && echo "Sorry, $feature only works with bash 4.0 or higher" >&2 && return 12
[ `type -t complete` != 'builtin' ] && echo "Sorry, $feature requires a bash that supports programmable command completion" >&2 && return 13
die () {
echo "(exit=$?) $#" >&2 && exit 42
}
ifSourced () { # do NOT exit(1) from this function!
local readonly tempfile=`pwd`/tmp--cli-completion--$$
rm -f $tempfile
$BASH ${BASH_ARGV[0]} --populateTempfile $tempfile
[ $? -eq 0 ] || return
[ -e $tempfile ] || return
. $tempfile
rm -f $tempfile
# # # Associate the completion function with the splunk binary.
local readonly completionFunction=fSplunkComplete
complete -r splunk 2>/dev/null
complete -F $completionFunction splunk
# You can view the completion function anytime via: $ type fSplunkComplete
}
ifInvoked () { # all error checking happens in this function
local readonly debug=false
local readonly tempfile=$1
$debug && echo "Told that tempfile=$tempfile"
# # # If anything goes wrong, at least we don't pollute cwd with our tempfile.
$debug || trap "rm -f $tempfile" SIGINT SIGQUIT SIGTERM SIGABRT SIGPIPE
touch $tempfile || die "Cannot touch tempfile=$tempfile"
# # # Decide where SPLUNK_HOME is.
if [ "$(dirname $(pwd))" == 'bin' ]; then
local readonly splunkHome=$(dirname $(dirname $(pwd)))
elif [ -n "$SPLUNK_HOME" ]; then
local readonly splunkHome=$SPLUNK_HOME
else
die 'Cannot figure out where SPLUNK_HOME is'
fi
$debug && echo "Decided SPLUNK_HOME=$splunkHome"
# # # Check that splunk (the binary) exists.
local readonly splunkBinary=$splunkHome/bin/splunk
[ -e $splunkBinary -a -x $splunkBinary ] || die "Cannot find expected binary=$splunkBinary"
# # # Find the file with object->{verb1,verb2,...} map.
local readonly splunkrcCmdsXml=$splunkHome/etc/system/static/splunkrc_cmds.xml
[ -e $splunkrcCmdsXml ] || die "Cannot find expected file $splunkrcCmdsXml"
$debug && echo "Shall read verb-obj info from: $splunkrcCmdsXml"
# # # Parse the map file, and generate our internal verb->{objA,objB,...} map.
local -A verb_to_objects
local line object verb objectsForThisVerb lineNumber=0
local inItem=false
local readonly regex_depr='\<depr\>'
local readonly regex_verb='\<verb\>'
local readonly regex_synonym='\<synonym\>'
while read line; do
lineNumber=$((lineNumber+1))
if $inItem; then
if [[ $line =~ '</item>' ]]; then
$debug && echo "Exited item tag at line=$lineNumber; this was obj=$object"
inItem=false
object=''
elif [[ $line =~ '<cmd name' && ! $line =~ $regex_depr && ! $line =~ $regex_synonym ]]; then
[ -z "$object" ] && die "BUG: No object within item tag. (At line $lineNumber of $splunkrcCmdsXml)"
verb=${line#*\"} # remove shortest match of .*" from the front
verb=${verb%%\"*} # remove longest match of ".* from the back
[ "$verb" == '_internal' ] && continue # Why the... eh, moving on.
objectsForThisVerb=${verb_to_objects[$verb]}
objectsForThisVerb="$objectsForThisVerb $object"
verb_to_objects[$verb]=$objectsForThisVerb
$debug && echo "Mapped object=$object to verb=$verb at line=$lineNumber; now objectsForThisVerb='$objectsForThisVerb'"
fi
else # ! inItem
if [[ $line =~ '<item obj' && ! $line =~ $regex_depr && ! $line =~ $regex_verb && ! $line =~ $regex_synonym ]]; then
inItem=true
object=${line#*\"} # remove shortest match of .*" from the front
object=${object%%\"*} # remove longest match of ".* from the back
$debug && echo "Entered item tag at line=$lineNumber, parsed object=$object"
[ "$object" == 'on' ] && inItem=false # Do not expose Amrit's puerile jest.
[ "$object" == 'help' ] && inItem=false # Although 'help' is a verb, splunkrc_cmds.xml constructs it as an object; ugh. We'll deal with the objects (topics) of 'splunk help' separately, below.
fi
fi
done < $splunkrcCmdsXml
$debug && echo "Processed $lineNumber lines. Map keys: ${!verb_to_objects[*]}, values: ${verb_to_objects[#]}"
# # # Oh wait, '<verb> deploy-server' aren't in splunkrc_cmds.xml; thanks, Jojy!!!!!
for verb in reload enable disable display; do
objectsForThisVerb=${verb_to_objects[$verb]}
objectsForThisVerb="$objectsForThisVerb deploy-server"
verb_to_objects[$verb]=$objectsForThisVerb
done
# # # Find the file with topics understood by 'splunk help <topic>' command, and extract list of topics.
local readonly literalsPy=$splunkHome/lib/python2.7/site-packages/splunk/clilib/literals.py
[ -e $literalsPy ] || die "Cannot find expected file $literalsPy"
$debug && echo "Shall read help topics list from: $literalsPy"
local readonly helpTopics=$(sed '/^addHelp/! d; s/^addHelp//; s/,.*$//; s/[^a-zA-Z_-]/ /g; s/^[ ]*//; s/[ ].*$//; /^$/ d' $literalsPy | sort | uniq)
$debug && echo "Parsed help topics list as: $helpTopics"
#######################################################
# # # Write the completion function to tempfile: BEGIN.
local readonly completionFunction=fSplunkComplete
echo -e 'function '$completionFunction' () {' >> $tempfile
echo -e '\tlocal wordCur=${COMP_WORDS[COMP_CWORD]}' >> $tempfile
echo -e '\tlocal wordPrev=${COMP_WORDS[COMP_CWORD-1]}' >> $tempfile
echo -e '\tcase $wordPrev in' >> $tempfile
# # # What can follow 'splunk' itself? Verbs used in main.c to key the 'cmd_handlers' array; and verbs from splunkrc_cmds.xml; and 'help'.
local readonly keys__cmd_handlers='ftr start startnoss stop restart restartss status rebuild train fsck clean-dispatch clean-srtemp validate verifyconfig anonymize find clean createssl juststopit migrate --version -version version httpport soapport spool ftw envvars _RAW_envvars _port_check cmd _rest_xml_dump search dispatch rtsearch livetail _normalizepath _internal logout btool pooling _web_bootstart offline clone-prep-clear-config diag'
local allVerbs="${!verb_to_objects[*]}"
echo -e '\t\tsplunk)\n\t\t\tCOMPREPLY=( $(compgen -W "'$keys__cmd_handlers $allVerbs' help" -- $wordCur) ) ;;' >> $tempfile
# # # What can follow 'splunk _internal'? see cmd_internal() of main.c
local readonly actions_internal='http mgmt https pre-flight-checks check-db call rpc rpc-auth soap-call soap-call-auth prefixcount totalcount check-xml-files first-time-run make-splunkweb-certs-and-var-run-merged'
echo -e '\t\t_internal)\n\t\t\tCOMPREPLY=( $(compgen -W "'$actions_internal'" -- $wordCur) ) ;;' >> $tempfile
# # # Options to 'splunk clean' are in CLI::clean() of src/main/Clean.cpp; to 'splunk fsck', in usageBanner of src/main/Fsck.cpp; to 'splunk migrate', in CLI::migrate() of src/main/Migration.cpp
echo -e '\t\tclean)\n\t\t\tCOMPREPLY=( $(compgen -W "all eventdata globaldata userdata inputdata locks deployment-artifacts raft" -- $wordCur) ) ;;' >> $tempfile
echo -e '\t\tfsck)\n\t\t\tCOMPREPLY=( $(compgen -W "scan repair clear-bloomfilter make-searchable" -- $wordCur) ) ;;' >> $tempfile
echo -e '\t\tmigrate)\n\t\t\tCOMPREPLY=( $(compgen -W "input-records to-modular-inputs rename-cluster-app" -- $wordCur) ) ;;' >> $tempfile
# # # List the help topics.
echo -e '\t\thelp)\n\t\t\tCOMPREPLY=( $(compgen -W "'$helpTopics'" -- $wordCur) ) ;;' >> $tempfile
# # # What can follow 'splunk cmd'? any executable in SPLUNK_HOME/bin/
echo -e '\t\tcmd)\n\t\t\tCOMPREPLY=( $(compgen -o default -o filenames -G "'$splunkHome'/bin/*" -- $wordCur) ) ;;' >> $tempfile
# # # Finally, let each verb be completed by its objects.
for verb in $allVerbs; do
echo -e '\t\t'$verb')\n\t\t\tCOMPREPLY=( $(compgen -W "'${verb_to_objects[$verb]}'" -- $wordCur) ) ;;' >> $tempfile
done
# # # And if we've run out of suggestions, revert to bash's default completion behavior: filename completion.
echo -e '\t\t*)\n\t\t\tCOMPREPLY=( $(compgen -f -- $wordCur) ) ;;' >> $tempfile
echo -e '\tesac' >> $tempfile
echo -e '}' >> $tempfile
$debug && cp $tempfile $tempfile~bak
# # # Write the completion function to tempfile: DONE.
######################################################
# # # Sanity check: source the tempfile, make sure that the function we wrote can be parsed and loaded by the shell.
unset $completionFunction
. $tempfile
[ "`type -t $completionFunction`" == 'function' ] || die 'BUG: generated completion function cannot be parsed by bash'
}
if [ $SHLVL -eq 1 ]; then
[ $# -ge 1 ] && echo "Ignoring supplied arguments: $#" >&2
ifSourced
elif [ $SHLVL -eq 2 ]; then
if [ $# -eq 2 ] && [ $1 == '--populateTempfile' ]; then
ifInvoked $2
else
echo -e "This script must be sourced, like so:\n\n\t\033[1m. $0\033[0m\n"
fi
else
: # user is running screen(1) or something of the sort.
fi
# # # Clean up.
unset die ifSourced ifInvoked
Edit2:
xtrace output
++ feature='"splunk <verb> <object>" tab-completion'
+++ basename /bin/bash
++ '[' bash '!=' bash ']'
++ '[' 4 -lt 4 ']'
+++ type -t complete
++ '[' builtin '!=' builtin ']'
++ '[' 1 -eq 1 ']'
++ '[' 0 -ge 1 ']'
++ ifSourced
+++ pwd
++ local readonly tempfile=/home/splunk/tmp--cli-completion--12431
++ rm -f /home/splunk/tmp--cli-completion--12431
++ /bin/sh cli-command-completion.sh --populateTempfile /home/splunk/tmp--cli-completion--12431
+ feature="splunk <verb> <object>" tab-completion
+ basename /bin/bash
+ [ bash != bash ]
cli-command-completion.sh: 8: cli-command-completion.sh: Bad substitution
++ '[' 2 -eq 0 ']'
++ return
++ unset die ifSourced ifInvoked
Edit3:
When using
set -o verbose
set -o noglob
set -o noglob
and checking differences between OK (root) and failing (non-root) run.
OK side:
[...]
+++ basename /bin/bash
++ '[' bash '!=' bash ']'
[ ${BASH_VERSINFO[0]} -lt 4 ] && echo "Sorry, $feature only works with bash 4.0 or higher" >&2 && return 12
++ '[' 4 -lt 4 ']'
[...]
++ local readonly tempfile=/home/splunk/tmp--cli-completion--42064
++ rm -f /home/splunk/tmp--cli-completion--42064
++ /bin/bash cli-command-completion.sh --populateTempfile /home/splunk/tmp--cli-completion--42064
+ set -o verbose
set -o noglob
+ set -o noglob
# Vainstein K 12aug2013
[...]
[ ${BASH_VERSINFO[0]} -lt 4 ] && echo "Sorry, $feature only works with bash 4.0 or higher" >&2 && return 12
+ '[' 4 -lt 4 ']'
[...]
Failing side:
[...]
+++ basename /bin/bash
++ '[' bash '!=' bash ']'
[ ${BASH_VERSINFO[0]} -lt 4 ] && echo "Sorry, $feature only works with bash 4.0 or higher" >&2 && return 12
++ '[' 4 -lt 4 ']'
[...]
++ local readonly tempfile=/home/splunk/tmp--cli-completion--40686
++ rm -f /home/splunk/tmp--cli-completion--40686
++ /bin/sh cli-command-completion.sh --populateTempfile /home/splunk/tmp--cli-completion--40686
+ set -o verbose
set -o noglob
+ set -o noglob
# Vainstein K 12aug2013
# # # Check a few prereqs.
feature='"splunk <verb> <object>" tab-completion'
+ feature="splunk <verb> <object>" tab-completion
[ `basename $SHELL` != 'bash' ] && echo "Sorry, $feature is only for bash" >&2 && return 11
+ basename /bin/bash
+ [ bash != bash ]
[ ${BASH_VERSINFO[0]} -lt 4 ] && echo "Sorry, $feature only works with bash 4.0 or higher" >&2 && return 12
cli-command-completion.sh: 10: cli-command-completion.sh: Bad substitution
++ '[' 2 -eq 0 ']'
++ return
# # # Clean up.
unset die ifSourced ifInvoked
++ unset die ifSourced ifInvoked
Seems like as non-root, it runs as /bin/sh whereas as 'bash' as root.
Weird because I tried multiple things to force bash there, maybe not the right ones.
It also fail at line 7 even though the first loop succeeds.
This should do the trick (line 7):
[ $(type -t complete) != 'builtin' ] && echo "Sorry, $feature requires a bash that supports programmable command completion" >&2 && return 13
Turns out from trace output that /bin/sh was used instead of /bin/bash to launch the script because /bin/bash was not set as default shell.
I have changed the default shell to /bin/bash and it is all ok now :)
I have used this method to set /bin/bash as default shell :
Check:
grep /etc/passwd
Change:
chsh --shell /bin/bash
Check modification:
grep /etc/passwd
Thanks for the help!
I might be blind, but I can't find the errors my script got, maybe you guys got better eyes than me :). I use a busybox compiled linux on a embedded system, Kernel 4.18.0. I found the base script here: Gist-Template
the following error is at "start":
./daemon: line 195: arithmetic syntax error
when I try "stop" these messages appear, but i dont see a unknown operand at line 0:
sh: 0: unknown operand
* Stopping Monitoring
my script:
#!/bin/sh
daemonName="Monitoring"
pidDir="."
pidFile="$pidDir/$daemonName.pid"
pidFile="$daemonName.pid"
logDir="."
# To use a dated log file.
# logFile="$logDir/$daemonName-"`date +"%Y-%m-%d"`".log"
# To use a regular log file.
logFile="$logDir/$daemonName.log"
# Log maxsize in KB
logMaxSize=1024 # 1mb
runInterval=300 # In seconds
doCommands() {
# This is where you put all the commands for the daemon.
echo "Running commands."
}
############################################################
# Below are the command functions
############################################################
hw_temp() {
cpu_temp=$(sensors|grep CPU|awk '{print $3}'|awk '{print ($0-int($0)<0.499)?int($0):int($0)+1}')
env_temp=$(sensors|grep ENV|awk '{print $3}'|awk '{print ($0-int($0)<0.499)?int($0):int($0)+1}')
pcb_temp=$(sensors|grep PCB|awk '{print $3}'|awk '{print ($0-int($0)<0.499)?int($0):int($0)+1}')
echo "$cpu_temp $env_temp $pcb_temp" >> /opt/monitoring/bla
}
############################################################
# Below is the skeleton functionality of the daemon.
############################################################
myPid=`echo $$`
setupDaemon() {
# Make sure that the directories work.
if [ ! -d "$pidDir" ]; then
mkdir "$pidDir"
fi
if [ ! -d "$logDir" ]; then
mkdir "$logDir"
fi
if [ ! -f "$logFile" ]; then
touch "$logFile"
else
# Check to see if we need to rotate the logs.
size=$((`ls -l "$logFile" | cut -d " " -f 8`/1024))
if [[ $size -gt $logMaxSize ]]; then
mv $logFile "$logFile.old"
touch "$logFile"
fi
fi
}
startDaemon() {
# Start the daemon.
setupDaemon # Make sure the directories are there.
if [[ `checkDaemon` = 1 ]]; then
echo " * \033[31;5;148mError\033[39m: $daemonName is already running."
exit 1
fi
echo " * Starting $daemonName with PID: $myPid."
echo "$myPid" > "$pidFile"
log '*** '`date +"%Y-%m-%d"`": Starting up $daemonName."
# Start the loop.
loop
}
stopDaemon() {
# Stop the daemon.
if [[ `checkDaemon` -eq 0 ]]; then
echo " * \033[31;5;148mError\033[39m: $daemonName is not running."
exit 1
fi
echo " * Stopping $daemonName"
log '*** '`date +"%Y-%m-%d"`": $daemonName stopped."
if [[ ! -z `cat $pidFile` ]]; then
kill -9 `cat "$pidFile"` &> /dev/null
fi
}
statusDaemon() {
# Query and return whether the daemon is running.
if [[ `checkDaemon` -eq 1 ]]; then
echo " * $daemonName is running."
else
echo " * $daemonName isn't running."
fi
exit 0
}
restartDaemon() {
# Restart the daemon.
if [[ `checkDaemon` = 0 ]]; then
# Can't restart it if it isn't running.
echo "$daemonName isn't running."
exit 1
fi
stopDaemon
startDaemon
}
checkDaemon() {
# Check to see if the daemon is running.
# This is a different function than statusDaemon
# so that we can use it other functions.
if [ -z "$oldPid" ]; then
return 0
elif [[ `ps aux | grep "$oldPid" | grep "$daemonName" | grep -v grep` > /dev/null ]]; then
if [ -f "$pidFile" ]; then
if [[ `cat "$pidFile"` = "$oldPid" ]]; then
# Daemon is running.
# echo 1
return 1
else
# Daemon isn't running.
return 0
fi
fi
elif [[ `ps aux | grep "$daemonName" | grep -v grep | grep -v "$myPid" | grep -v "0:00.00"` > /dev/null ]]; then
# Daemon is running but without the correct PID. Restart it.
log '*** '`date +"%Y-%m-%d"`": $daemonName running with invalid PID; restarting."
restartDaemon
return 1
else
# Daemon not running.
return 0
fi
return 1
}
loop() {
# This is the loop.
now=`date +%s`
if [ -z $last ]; then
last=`date +%s`
fi
# Do everything you need the daemon to do.
doCommands
# Check to see how long we actually need to sleep for. If we want this to run
# once a minute and it's taken more than a minute, then we should just run it
# anyway.
last=`date +%s`
# Set the sleep interval
if [[ ! $((now-last+runInterval+1)) -lt $((runInterval)) ]]; then
sleep $((now-last+runInterval))
fi
# Startover
loop
}
log() {
# Generic log function.
echo "$1" >> "$logFile"
}
###############################################################
# Parse the command.
###############################################################
if [ -f "$pidFile" ]; then
oldPid=`cat "$pidFile"`
fi
checkDaemon
case "$1" in
start)
startDaemon
;;
stop)
stopDaemon
;;
status)
statusDaemon
;;
restart)
restartDaemon
;;
*)
echo "Error: usage $0 { start | stop | restart | status }"
exit 1
esac
exit 0
Trying to deploy jboss eap 7 server in linux environment which got deployed in windows (same server configuration is working fine in windows) giving this issue
RROR [org.springframework.web.context.ContextLoader] (ServerService Thread Pool -- 103) Context initialization failed:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reportBeanService':
Invocation of init method failed; nested exception is javax.naming.NamingException: WFLYNAM0062:
Failed to lookup EAR_Name/Module/Bean!com.src.ejb.BeanRemote [Root exception is java.lang.NoClassDefFoundError: Could not initialize Class com.sun.proxy.$Proxy73]
Any idea what can be the issue here or if you guys have faced the same issue please respond
this is my standalone.sh (this is the only file which is different from my windows version)
#!/bin/sh
# Use --debug to activate debug mode with an optional argument to specify the port.
# Usage : standalone.sh --debug
# standalone.sh --debug 9797
# By default debug mode is disable.
DEBUG_MODE="${DEBUG:-false}"
DEBUG_PORT="${DEBUG_PORT:-8787}"
SERVER_OPTS=""
while [ "$#" -gt 0 ]
do
case "$1" in
--debug)
DEBUG_MODE=true
if [ -n "$2" ] && [ "$2" = `echo "$2" | sed 's/-//'` ]; then
DEBUG_PORT=$2
shift
fi
;;
-Djava.security.manager*)
echo "ERROR: The use of -Djava.security.manager has been removed. Please use the -secmgr command line argument or SECMGR=true environment variable."
exit 1
;;
-secmgr)
SECMGR="true"
;;
--)
shift
break;;
*)
SERVER_OPTS="$SERVER_OPTS '$1'"
;;
esac
shift
done
DIRNAME=`dirname "$0"`
PROGNAME=`basename "$0"`
GREP="grep"
# Use the maximum available, or set MAX_FD != -1 to use that
MAX_FD="maximum"
# OS specific support (must be 'true' or 'false').
cygwin=false;
darwin=false;
linux=false;
solaris=false;
freebsd=false;
other=false
case "`uname`" in
CYGWIN*)
cygwin=true
;;
Darwin*)
darwin=true
;;
FreeBSD)
freebsd=true
;;
Linux)
linux=true
;;
SunOS*)
solaris=true
;;
*)
other=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$JBOSS_HOME" ] &&
JBOSS_HOME=`cygpath --unix "$JBOSS_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$JAVAC_JAR" ] &&
JAVAC_JAR=`cygpath --unix "$JAVAC_JAR"`
fi
# Setup JBOSS_HOME
RESOLVED_JBOSS_HOME=`cd "$DIRNAME/.." >/dev/null; pwd`
if [ "x$JBOSS_HOME" = "x" ]; then
# get the full path (without any relative bits)
JBOSS_HOME=$RESOLVED_JBOSS_HOME
else
SANITIZED_JBOSS_HOME=`cd "$JBOSS_HOME"; pwd`
if [ "$RESOLVED_JBOSS_HOME" != "$SANITIZED_JBOSS_HOME" ]; then
echo ""
echo " WARNING: JBOSS_HOME may be pointing to a different installation - unpredictable results may occur."
echo ""
echo " JBOSS_HOME: $JBOSS_HOME"
echo ""
sleep 2s
fi
fi
export JBOSS_HOME
# Read an optional running configuration file
if [ "x$RUN_CONF" = "x" ]; then
RUN_CONF="$DIRNAME/standalone.conf"
fi
if [ -r "$RUN_CONF" ]; then
. "$RUN_CONF"
fi
JAVA_OPTS="-Denvprop.loc="/home/user1/wildfly-10.0.0.Final/bin/environment.properties" -Djboss.ejb.client.properties.file.path="/home/user1/wildfly-10.0.0.Final/bin/jboss-ejb-client.properties" -Dfa.dfprimary=DFSERVER1 -Dfa.dfsecondary=DFSERVER1 -Dfa.servername=DFSERVER1 -Dfa.init.log4j=true -Dfa.log.config.location="/home/scm/FirstGen_JBOSS7/config/log4j.xml" -DLog2DB=true -server -agentlib:jdwp=transport=dt_socket,address=9999,server=y,suspend=n"
# Set debug settings if not already set
if [ "$DEBUG_MODE" = "true" ]; then
DEBUG_OPT=`echo $JAVA_OPTS | $GREP "\-agentlib:jdwp"`
if [ "x$DEBUG_OPT" = "x" ]; then
JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,address=$DEBUG_PORT,server=y,suspend=n"
else
echo "Debug already enabled in JAVA_OPTS, ignoring --debug argument"
fi
fi
# Setup the JVM
if [ "x$JAVA" = "x" ]; then
if [ "x$JAVA_HOME" != "x" ]; then
JAVA="$JAVA_HOME/bin/java"
else
JAVA="java"
fi
fi
if [ "$PRESERVE_JAVA_OPTS" != "true" ]; then
# Check for -d32/-d64 in JAVA_OPTS
JVM_D64_OPTION=`echo $JAVA_OPTS | $GREP "\-d64"`
JVM_D32_OPTION=`echo $JAVA_OPTS | $GREP "\-d32"`
# Check If server or client is specified
SERVER_SET=`echo $JAVA_OPTS | $GREP "\-server"`
CLIENT_SET=`echo $JAVA_OPTS | $GREP "\-client"`
if [ "x$JVM_D32_OPTION" != "x" ]; then
JVM_OPTVERSION="-d32"
elif [ "x$JVM_D64_OPTION" != "x" ]; then
JVM_OPTVERSION="-d64"
elif $darwin && [ "x$SERVER_SET" = "x" ]; then
# Use 32-bit on Mac, unless server has been specified or the user opts are incompatible
"$JAVA" -d32 $JAVA_OPTS -version > /dev/null 2>&1 && PREPEND_JAVA_OPTS="-d32" && JVM_OPTVERSION="-d32"
fi
if [ "x$CLIENT_SET" = "x" -a "x$SERVER_SET" = "x" ]; then
# neither -client nor -server is specified
if $darwin && [ "$JVM_OPTVERSION" = "-d32" ]; then
# Prefer client for Macs, since they are primarily used for development
PREPEND_JAVA_OPTS="$PREPEND_JAVA_OPTS -client"
else
PREPEND_JAVA_OPTS="$PREPEND_JAVA_OPTS -server"
fi
fi
# EAP6-121 feature disabled
# Enable rotating GC logs if the JVM supports it and GC logs are not already enabled
#NO_GC_LOG_ROTATE=`echo $JAVA_OPTS | $GREP "\-verbose:gc"`
#if [ "x$NO_GC_LOG_ROTATE" = "x" ]; then
# backup prior gc logs
#mv "$JBOSS_LOG_DIR/gc.log.0" "$JBOSS_LOG_DIR/backupgc.log.0" >/dev/null 2>&1
#mv "$JBOSS_LOG_DIR/gc.log.1" "$JBOSS_LOG_DIR/backupgc.log.1" >/dev/null 2>&1
#mv "$JBOSS_LOG_DIR/gc.log.2" "$JBOSS_LOG_DIR/backupgc.log.2" >/dev/null 2>&1
#mv "$JBOSS_LOG_DIR/gc.log.3" "$JBOSS_LOG_DIR/backupgc.log.3" >/dev/null 2>&1
#mv "$JBOSS_LOG_DIR/gc.log.4" "$JBOSS_LOG_DIR/backupgc.log.4" >/dev/null 2>&1
#mv "$JBOSS_LOG_DIR/gc.log.*.current" "$JBOSS_LOG_DIR/backupgc.log.current" >/dev/null 2>&1
#"$JAVA" $JVM_OPTVERSION -verbose:gc -Xloggc:"$JBOSS_LOG_DIR/gc.log" -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=3M -XX:-TraceClassUnloading -version >/dev/null 2>&1 && mkdir -p $JBOSS_LOG_DIR && PREPEND_JAVA_OPTS="$PREPEND_JAVA_OPTS -verbose:gc -Xloggc:\"$JBOSS_LOG_DIR/gc.log\" -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=3M -XX:-TraceClassUnloading"
#fi
JAVA_OPTS="$PREPEND_JAVA_OPTS $JAVA_OPTS"
fi
if [ "x$JBOSS_MODULEPATH" = "x" ]; then
JBOSS_MODULEPATH="$JBOSS_HOME/modules"
fi
if $linux; then
# consolidate the server and command line opts
CONSOLIDATED_OPTS="$JAVA_OPTS $SERVER_OPTS"
# process the standalone options
for var in $CONSOLIDATED_OPTS
do
# Remove quotes
p=`echo $var | tr -d "'"`
case $p in
-Djboss.server.base.dir=*)
JBOSS_BASE_DIR=`readlink -m ${p#*=}`
;;
-Djboss.server.log.dir=*)
JBOSS_LOG_DIR=`readlink -m ${p#*=}`
;;
-Djboss.server.config.dir=*)
JBOSS_CONFIG_DIR=`readlink -m ${p#*=}`
;;
esac
done
fi
if $solaris; then
# consolidate the server and command line opts
CONSOLIDATED_OPTS="$JAVA_OPTS $SERVER_OPTS"
# process the standalone options
for var in $CONSOLIDATED_OPTS
do
# Remove quotes
p=`echo $var | tr -d "'"`
case $p in
-Djboss.server.base.dir=*)
JBOSS_BASE_DIR=`echo $p | awk -F= '{print $2}'`
;;
-Djboss.server.log.dir=*)
JBOSS_LOG_DIR=`echo $p | awk -F= '{print $2}'`
;;
-Djboss.server.config.dir=*)
JBOSS_CONFIG_DIR=`echo $p | awk -F= '{print $2}'`
;;
esac
done
fi
# No readlink -m on BSD
if $darwin || $freebsd || $other ; then
# consolidate the server and command line opts
CONSOLIDATED_OPTS="$JAVA_OPTS $SERVER_OPTS"
# process the standalone options
for var in $CONSOLIDATED_OPTS
do
# Remove quotes
p=`echo $var | tr -d "'"`
case $p in
-Djboss.server.base.dir=*)
JBOSS_BASE_DIR=`cd ${p#*=} ; pwd -P`
;;
-Djboss.server.log.dir=*)
if [ -d "${p#*=}" ]; then
JBOSS_LOG_DIR=`cd ${p#*=} ; pwd -P`
else
#since the specified directory doesn't exist we don't validate it
JBOSS_LOG_DIR=${p#*=}
fi
;;
-Djboss.server.config.dir=*)
JBOSS_CONFIG_DIR=`cd ${p#*=} ; pwd -P`
;;
esac
done
fi
# determine the default base dir, if not set
if [ "x$JBOSS_BASE_DIR" = "x" ]; then
JBOSS_BASE_DIR="$JBOSS_HOME/standalone"
fi
# determine the default log dir, if not set
if [ "x$JBOSS_LOG_DIR" = "x" ]; then
JBOSS_LOG_DIR="$JBOSS_BASE_DIR/log"
fi
# determine the default configuration dir, if not set
if [ "x$JBOSS_CONFIG_DIR" = "x" ]; then
JBOSS_CONFIG_DIR="$JBOSS_BASE_DIR/configuration"
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
JBOSS_HOME=`cygpath --path --windows "$JBOSS_HOME"`
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
JBOSS_MODULEPATH=`cygpath --path --windows "$JBOSS_MODULEPATH"`
JBOSS_BASE_DIR=`cygpath --path --windows "$JBOSS_BASE_DIR"`
JBOSS_LOG_DIR=`cygpath --path --windows "$JBOSS_LOG_DIR"`
JBOSS_CONFIG_DIR=`cygpath --path --windows "$JBOSS_CONFIG_DIR"`
fi
if [ "x$JBOSS_MODULEPATH" = "x" ]; then
JBOSS_MODULEPATH="$JBOSS_HOME/modules"
fi
# Process the JAVA_OPTS and fail the script of a java.security.manager was found
SECURITY_MANAGER_SET=`echo $JAVA_OPTS | $GREP "java\.security\.manager"`
if [ "x$SECURITY_MANAGER_SET" != "x" ]; then
echo "ERROR: The use of -Djava.security.manager has been removed. Please use the -secmgr command line argument or SECMGR=true environment variable."
exit 1
fi
# Set up the module arguments
MODULE_OPTS=""
if [ "$SECMGR" = "true" ]; then
MODULE_OPTS="$MODULE_OPTS -secmgr";
fi
# Display our environment
echo "========================================================================="
echo ""
echo " JBoss Bootstrap Environment"
echo ""
echo " JBOSS_HOME: $JBOSS_HOME"
echo ""
echo " JAVA: $JAVA"
echo ""
echo " JAVA_OPTS: $JAVA_OPTS"
echo ""
echo "========================================================================="
echo ""
while true; do
if [ "x$LAUNCH_JBOSS_IN_BACKGROUND" = "x" ]; then
# Execute the JVM in the foreground
eval \"$JAVA\" -D\"[Standalone]\" $JAVA_OPTS \
\"-Dorg.jboss.boot.log.file="$JBOSS_LOG_DIR"/server.log\" \
\"-Dlogging.configuration=file:"$JBOSS_CONFIG_DIR"/logging.properties\" \
-jar \""$JBOSS_HOME"/jboss-modules.jar\" \
$MODULE_OPTS \
-mp \""${JBOSS_MODULEPATH}"\" \
org.jboss.as.standalone \
-Djboss.home.dir=\""$JBOSS_HOME"\" \
-Djboss.server.base.dir=\""$JBOSS_BASE_DIR"\" \
"$SERVER_OPTS"
JBOSS_STATUS=$?
else
# Execute the JVM in the background
eval \"$JAVA\" -D\"[Standalone]\" $JAVA_OPTS \
\"-Dorg.jboss.boot.log.file="$JBOSS_LOG_DIR"/server.log\" \
\"-Dlogging.configuration=file:"$JBOSS_CONFIG_DIR"/logging.properties\" \
-jar \""$JBOSS_HOME"/jboss-modules.jar\" \
$MODULE_OPTS \
-mp \""${JBOSS_MODULEPATH}"\" \
org.jboss.as.standalone \
-Djboss.home.dir=\""$JBOSS_HOME"\" \
-Djboss.server.base.dir=\""$JBOSS_BASE_DIR"\" \
"$SERVER_OPTS" "&"
JBOSS_PID=$!
# Trap common signals and relay them to the jboss process
trap "kill -HUP $JBOSS_PID" HUP
trap "kill -TERM $JBOSS_PID" INT
trap "kill -QUIT $JBOSS_PID" QUIT
trap "kill -PIPE $JBOSS_PID" PIPE
trap "kill -TERM $JBOSS_PID" TERM
if [ "x$JBOSS_PIDFILE" != "x" ]; then
echo $JBOSS_PID > $JBOSS_PIDFILE
fi
# Wait until the background process exits
WAIT_STATUS=128
while [ "$WAIT_STATUS" -ge 128 ]; do
wait $JBOSS_PID 2>/dev/null
WAIT_STATUS=$?
if [ "$WAIT_STATUS" -gt 128 ]; then
SIGNAL=`expr $WAIT_STATUS - 128`
SIGNAL_NAME=`kill -l $SIGNAL`
echo "*** JBossAS process ($JBOSS_PID) received $SIGNAL_NAME signal ***" >&2
fi
done
if [ "$WAIT_STATUS" -lt 127 ]; then
JBOSS_STATUS=$WAIT_STATUS
else
JBOSS_STATUS=0
fi
if [ "$JBOSS_STATUS" -ne 10 ]; then
# Wait for a complete shudown
wait $JBOSS_PID 2>/dev/null
fi
if [ "x$JBOSS_PIDFILE" != "x" ]; then
grep "$JBOSS_PID" $JBOSS_PIDFILE && rm $JBOSS_PIDFILE
fi
fi
if [ "$JBOSS_STATUS" -eq 10 ]; then
echo "Restarting application server..."
else
exit $JBOSS_STATUS
fi
done
This is an interesting snippet:
Failed to lookup FG_PMD_N6.2.2.4_20170828/ficclaim/ClaimsWebServiceBean!com.firstapex.fic.claims.ejb.ClaimsWebServiceBeanRemote
So it looks like a problem with a user application.
Maybe start with a 'clean' jboss application server (no user apps), then deploy them one by one. You might get some clues as the troubled application deploys.
What i want to do should be pretty simple, on my own i have reached the solution below, all i need is a few pointers to tell me if this is the way to do it or i should refactor anything in the code.
The below code, should create a few parallel processes and wait for them to finish executing then rerun the code again and again and again...
The script is triggered by a cron job once at 10 minutes, if the script is running, then do nothing, otherwise start the working process.
Any insight is highly appreciated since i am not that familiar with bash programming.
#!/bin/bash
# paths
THISPATH="$( cd "$( dirname "$0" )" && pwd )"
# make sure we move in the working directory
cd $THISPATH
# console init path
CONSOLEPATH="$( cd ../../ && pwd )/console.php"
# command line arguments
daemon=0
PHPPATH="/usr/bin/php"
help=0
# flag for binary search
LOOKEDFORPHP=0
# arguments init
while getopts d:p:h: opt; do
case $opt in
d)
daemon=$OPTARG
;;
p)
PHPPATH=$OPTARG
LOOKEDFORPHP=1
;;
h)
help=$OPTARG
;;
esac
done
shift $((OPTIND - 1))
# allow only one process
processesLength=$(ps aux | grep -v "grep" | grep -c $THISPATH/send-campaigns-daemon.sh)
if [ ${processesLength:-0} -gt 2 ]; then
# The process is already running
exit 0
fi
if [ $help -eq 1 ]; then
echo "---------------------------------------------------------------"
echo "| Usage: send-campaigns-daemon.sh |"
echo "| To force PHP CLI binary : |"
echo "| send-campaigns-daemon.sh -p /path/to/php-cli/binary |"
echo "---------------------------------------------------------------"
exit 0
fi
# php executable path, find it if not provided
if [ $PHPPATH ] && [ ! -f $PHPPATH ] && [ $LOOKEDFORPHP -eq 0 ]; then
phpVariants=( "php-cli" "php5-cli" "php5" "php" )
LOOKEDFORPHP=1
for i in "${phpVariants[#]}"
do
which $i >/dev/null 2>&1
if [ $? -eq 0 ]; then
PHPPATH=$(which $i)
fi
done
fi
if [ ! $PHPPATH ] || [ ! -f $PHPPATH ]; then
# Did not find PHP
exit 1
fi
# load options from app
parallelProcessesPerCampaign=3
campaignsAtOnce=10
subscribersAtOnce=300
sleepTime=30
function loadOptions {
local COMMAND="$PHPPATH $CONSOLEPATH option get_option --name=%s --default=%d"
parallelProcessesPerCampaign=$(printf "$COMMAND" "system.cron.send_campaigns.parallel_processes_per_campaign" 3)
campaignsAtOnce=$(printf "$COMMAND" "system.cron.send_campaigns.campaigns_at_once" 10)
subscribersAtOnce=$(printf "$COMMAND" "system.cron.send_campaigns.subscribers_at_once" 300)
sleepTime=$(printf "$COMMAND" "system.cron.send_campaigns.pause" 30)
parallelProcessesPerCampaign=$($parallelProcessesPerCampaign)
campaignsAtOnce=$($campaignsAtOnce)
subscribersAtOnce=$($subscribersAtOnce)
sleepTime=$($sleepTime)
}
# define the daemon function that will stay in loop
function daemon {
loadOptions
local pids=()
local k=0
local i=0
local COMMAND="$PHPPATH -q $CONSOLEPATH send-campaigns --campaigns_offset=%d --campaigns_limit=%d --subscribers_offset=%d --subscribers_limit=%d --parallel_process_number=%d --parallel_processes_count=%d --usleep=%d --from_daemon=1"
while [ $i -lt $campaignsAtOnce ]
do
while [ $k -lt $parallelProcessesPerCampaign ]
do
parallelProcessNumber=$(( $k + 1 ))
usleep=$(( $k * 10 + $i * 10 ))
CMD=$(printf "$COMMAND" $i 1 $(( $subscribersAtOnce * $k )) $subscribersAtOnce $parallelProcessNumber $parallelProcessesPerCampaign $usleep)
$CMD > /dev/null 2>&1 &
pids+=($!)
k=$(( k + 1 ))
done
i=$(( i + 1 ))
done
waitForPids pids
sleep $sleepTime
daemon
}
function daemonize {
$THISPATH/send-campaigns-daemon.sh -d 1 -p $PHPPATH > /dev/null 2>&1 &
}
function waitForPids {
stillRunning=0
for i in "${pids[#]}"
do
if ps -p $i > /dev/null
then
stillRunning=1
break
fi
done
if [ $stillRunning -eq 1 ]; then
sleep 0.5
waitForPids pids
fi
return 0
}
if [ $daemon -eq 1 ]; then
daemon
else
daemonize
fi
exit 0
when starting a script, create a lock file to know that this script is running. When the script finish, delete the lock file. If somebody kill the process while it is running, the lock file remain forever, though test how old it is and delete after if older than a defined value. For example,
#!/bin/bash
# 10 min
LOCK_MAX=600
typedef LOCKFILE=/var/lock/${0##*/}.lock
if [[ -f $LOCKFILE ]] ; then
TIMEINI=$( stat -c %X $LOCKFILE )
SEGS=$(( $(date +%s) - $TIEMPOINI ))
if [[ $SEGS -gt $LOCK_MAX ]] ; then
reportLocking or somethig to inform you
# Kill old intance ???
OLDPID=$(<$LOCKFILE)
[[ -e /proc/$OLDPID ]] && kill -9 $OLDPID
# Next time that the program is run, there is no lock file and it will run.
rm $LOCKFILE
fi
exit 65
fi
# Save PID of this instance to the lock file
echo "$$" > $LOCKFILE
### Your code go here
# Remove the lock file before script finish
[[ -e $LOCKFILE ]] && rm $LOCKFILE
exit 0
from here:
#!/bin/bash
...
echo PARALLEL_JOBS:${PARALLEL_JOBS:=1}
declare -a tests=($(.../find_what_to_run))
echo "${tests[#]}" | \
xargs -d' ' -n1 -P${PARALLEL_JOBS} -I {} bash -c ".../run_that {}" || { echo "FAILURE"; exit 1; }
echo "SUCCESS"
and here you can nick the code for portable locking with fuser
Okay, so i guess i can answer to my own question with a proper answer that works after many tests.
So here is the final version, simplified, without comments/echo :
#!/bin/bash
sleep 2
DIR="$( cd "$( dirname "$0" )" && pwd )"
FILE_NAME="$( basename "$0" )"
COMMAND_FILE_PATH="$DIR/$FILE_NAME"
if [ ! -f "$COMMAND_FILE_PATH" ]; then
exit 1
fi
cd $DIR
CONSOLE_PATH="$( cd ../../ && pwd )/console.php"
PHP_PATH="/usr/bin/php"
help=0
LOOKED_FOR_PHP=0
while getopts p:h: opt; do
case $opt in
p)
PHP_PATH=$OPTARG
LOOKED_FOR_PHP=1
;;
h)
help=$OPTARG
;;
esac
done
shift $((OPTIND - 1))
if [ $help -eq 1 ]; then
printf "%s\n" "HELP INFO"
exit 0
fi
if [ "$PHP_PATH" ] && [ ! -f "$PHP_PATH" ] && [ "$LOOKED_FOR_PHP" -eq 0 ]; then
php_variants=( "php-cli" "php5-cli" "php5" "php" )
LOOKED_FOR_PHP=1
for i in "${php_variants[#]}"
do
which $i >/dev/null 2>&1
if [ $? -eq 0 ]; then
PHP_PATH="$(which $i)"
break
fi
done
fi
if [ ! "$PHP_PATH" ] || [ ! -f "$PHP_PATH" ]; then
exit 1
fi
LOCK_BASE_PATH="$( cd ../../../common/runtime && pwd )/shell-pids"
LOCK_PATH="$LOCK_BASE_PATH/send-campaigns-daemon.pid"
function remove_lock {
if [ -d "$LOCK_PATH" ]; then
rmdir "$LOCK_PATH" > /dev/null 2>&1
fi
exit 0
}
if [ ! -d "$LOCK_BASE_PATH" ]; then
if ! mkdir -p "$LOCK_BASE_PATH" > /dev/null 2>&1; then
exit 1
fi
fi
process_running=0
if mkdir "$LOCK_PATH" > /dev/null 2>&1; then
process_running=0
else
process_running=1
fi
if [ $process_running -eq 1 ]; then
exit 0
fi
trap "remove_lock" 1 2 3 15
COMMAND="$PHP_PATH $CONSOLE_PATH option get_option --name=%s --default=%d"
parallel_processes_per_campaign=$(printf "$COMMAND" "system.cron.send_campaigns.parallel_processes_per_campaign" 3)
campaigns_at_once=$(printf "$COMMAND" "system.cron.send_campaigns.campaigns_at_once" 10)
subscribers_at_once=$(printf "$COMMAND" "system.cron.send_campaigns.subscribers_at_once" 300)
sleep_time=$(printf "$COMMAND" "system.cron.send_campaigns.pause" 30)
parallel_processes_per_campaign=$($parallel_processes_per_campaign)
campaigns_at_once=$($campaigns_at_once)
subscribers_at_once=$($subscribers_at_once)
sleep_time=$($sleep_time)
k=0
i=0
pp=0
COMMAND="$PHP_PATH -q $CONSOLE_PATH send-campaigns --campaigns_offset=%d --campaigns_limit=%d --subscribers_offset=%d --subscribers_limit=%d --parallel_process_number=%d --parallel_processes_count=%d --usleep=%d --from_daemon=1"
while [ $i -lt $campaigns_at_once ]
do
while [ $k -lt $parallel_processes_per_campaign ]
do
parallel_process_number=$(( $k + 1 ))
usleep=$(( $k * 10 + $i * 10 ))
CMD=$(printf "$COMMAND" $i 1 $(( $subscribers_at_once * $k )) $subscribers_at_once $parallel_process_number $parallel_processes_per_campaign $usleep)
$CMD > /dev/null 2>&1 &
k=$(( k + 1 ))
pp=$(( pp + 1 ))
done
i=$(( i + 1 ))
done
wait
sleep ${sleep_time:-30}
$COMMAND_FILE_PATH -p "$PHP_PATH" > /dev/null 2>&1 &
remove_lock
exit 0
Usually, it is a lock file, not a lock path. You hold the PID in the lock file for monitoring your process. In this case your lock directory does not hold any PID information. Your script also does not do any PID file/directory maintenance when it starts in case of a improper shutdown of your process without cleaning of your lock.
I like your first script better with this in mind. Monitoring the PID's running directly is cleaner. The only problem is if you start a second instance with cron, it is not aware of the PID's connect to the first instance.
You also have processLength -gt 2 which is 2, not 1 process running so you will duplicate your process threads.
It seems also that daemonize is just recalling the script with daemon which is not very useful. Also, having a variable with the same name as a function is not effective.
The correct way to make a lockfile is like this:
# Create a temporary file
echo $$ > ${LOCKFILE}.tmp$$
# Try the lock; ln without -f is atomic
if ln ${LOCKFILE}.tmp$$ ${LOCKFILE}; then
# we got the lock
else
# we didn't get the lock
fi
# Tidy up the temporary file
rm ${LOCKFILE}.tmp$$
And to release the lock:
# Unlock
rm ${LOCKFILE}
The key thing is to create the lock file to one side, using a unique name, and then try to link it to the real name. This is an atomic operation, so it should be safe.
Any solution that does "test and set" gives you a race condition to deal with. Yes, that can be sorted out, but you end up write extra code.
with all the kind replies to my last question I have been able to create a small script to check temperatures on my NAS but now I am struggling on sending it to the background. When I try to start my script with
sh temp_check.sh start
I get an error pointing to this line
$0 background &
and I can't figure out why :/
This is my whole script
#!/ffp/bin/sh
#
#check CPU and HDD temperature and shutdown if too hot
#Settings
cpu_high=60
hdd_high=50
NAME="temp_check"
PIDFILE="/var/run/$NAME.pid"
Background() {
echo $$ >$PIDFILE
exec >/dev/null 2>&1
trap "rm -f $PIDFILE ; exit 0" INT TERM EXIT
while true; do
STATE=$(hdparm -C /dev/sda1 | grep "drive state" | awk '{print $4}')
if [ "$STATE" = "active/idle" ]; then
hdd_temp=$(/usr/local/zy-pkgs/bin/smartctl -A -d marvell /dev/sda | grep 194 | cut -d: -f3 | awk '{print $10}')
cpu_temp=$(i2cget -y 0x0 0x0a 0x07)
printf -v cpu_res "%d" "$cpu_temp"
if [[ $cpu_res -lt $cpu_high && $hdd_temp -lt $hdd_high ]]; then
#echo "CPU und HDD Temperaturen in Ordnung"
sleep 30
else
halt
fi
else
cpu_temp=$(i2cget -y 0x0 0x0a 0x07)
printf -v cpu_res "%d" "$cpu_temp"
if [ $cpu_res -lt $cpu_high ]; then
#echo "CPU Temperatur in Ordnung - HDD im Standby Modus"
sleep 30
else
halt
fi
fi
done
}
case $1 in
start)
[ -f $PIDFILE ] && [ -f /proc/` cat $PIDFILE `/cmdline ] && echo "already running. Aborting." && exit 1
$0 background &
echo "Starting $NAME..."
;;
stop)
kill -9 ` cat $PIDFILE ` >/dev/null 2>&1
echo "Stopping $NAME ` cat $PIDFILE ` "
;;
status)
[ -f $PIDFILE ] && [ -f /proc/` cat $PIDFILE `/cmdline ] && echo "running as ` cat $PIDFILE ` " && exit 0
echo "not running"
;;
background)
Background
;;
*)
echo "use $0 [ start | stop | status ]"
;;
esac
Any help is appreciated
Cheers
Moritz
One possible error is, that the script is not executable. If this is the case, you can either fix the line to
/bin/sh $0 background &
or make the script executable with
chmod a+x temp_check.sh
maybe it helps, if you change your Background() function to something like
Background()
{ (
...
) &
}
and just call Background in your "start". That's much simpler.