I have a script which allows me to restart my running Xserver. However, whenever the Xserver run back again, all the contents of xinitrc.d folder aren't applied.
rm /tmp/startx.logs
LOOPTC=0
while [ $LOOPTC -eq 0 ]
do
pidof TerminalConfig 1>/dev/null 2>/dev/null
LOOPTC=$?
sleep 1
echo Tc not closed >> /tmp/startx.logs
done
killall gdm 2>/dev/null &
pkill x
if grep ^AUTOLOGIN /etc/sysconfig/autologin | egrep "NO|no|No|nO" ; then
echo autologin off >> /tmp/startx.logs
LOOPX=0
while [ $LOOPX -eq 0 ]
do
pidof X 1>/dev/null 2>/dev/null
LOOPX=$?
sleep 1
echo X not closed >> /tmp/startx.logs
done
fi
clear >> /dev/tty1
for (( i=0; i<4; i++ )) ; do
sleep 1
echo Please wait while restarting X11 Windows... >> /dev/tty1
done
clear >> /dev/tty1
ps ax | grep startx > /tmp/startx.result
sed -e s/.*grep.*//g -e /^$/d /tmp/startx.result -i
echo $(date) :startx: >> /tmp/startx.logs
cat /tmp/startx.result >> /tmp/startx.logs
if [ -s /tmp/startx.result ] ; then
echo Thu Feb 1 22:50:08 UTC 2018 :startx already running, no need to execute startx >> /tmp/startx.logs
else
killall gdm 2>/dev/null &
startx
echo $(date) :startx not running, executing startx >> /tmp/startx.logs
fi
if grep --quiet if [ ! /etc/X11/xinit/xinitrc; then
cp -f /etc/X11/xinit/xinitrc.old /etc/X11/xinit/xinitrc
rm -f /tmp/startx.result
#rm -f /tmp/restart-x.sh
Note that this script is always run on the Xserver. All the xinitrc.d contents are always applied whenever I run startx from the console (without Xserver running).
I'm wondering, why aren't the xinitrc.d files applied even if I have already ensured that the contents of the xinitrc.d folder should be applied using a for-loop and placed it in the xinitrc file?
Related
txt with more than 30000 records.
All records are one for line and is an IP like this:
192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5
192.168.0.6
192.168.0.7
192.168.0.8
192.168.0.9
192.168.0.10
I read each row in a bash script, and I need to run a curl like this:
while IFS= read -r line || [[ -n "$line" ]]; do
#check_site "$line"
resp=$(curl -i -m1 http://$line 2>&1)
echo "$resp" | grep -Eo "$ok" > /dev/null
if [ $? -ne 0 ]; then
#echo -e "failed: $line" >> "${logfile}"
echo -e "Command: curl -i -m1 http://$line 2>&1" >> "${outfile}"
echo -e "failed: $line:\n\n \"$resp\"\n\n" >> "${outfile}"
echo "$line" >> "${faillog}"
fi
done < "${FILE}"
Is there a method to run multiple lines simultaneously in my file to reduce the execution time?
I solved for the multiprocess in this way:
#export variable to be used into function
export outlog="/tmp/out.log"
export faillog="/tmp/fail.log"
export ok="(curl: \(7\) Failed to connect to)" # acceptable responses
# create function:
check_site() {
ip=$1
resp=$(curl -i -m1 http://$ip 2>&1)
echo "$resp" | grep -Eo "$ok" > /dev/null
if [ $? -ne 0 ]; then
echo -e "Command: curl -i -m1 http://$ip 2>&1" >> "${outlog}"
echo -e "Block failed: $ip:\n\n \"$resp\"\n\n" >> "${outlog}"
echo "$ip" >> "${faillog}"
fi
}
# call the function:
export -f check_site
parallel -j 252 -a "${FILE}" check_site
Xargs will do the trick. Wikipedia
This article describe approach to resolve parallel execution, it may help you:
Parallel execution in Bash
Example from the article:
#!/bin/bash
RANDOM=10
JOBS_COUNTER=0
MAX_CHILDREN=10
MY_PID=$$
for i in {1..100}
do
echo Cycle counter: $i
JOBS_COUNTER=$((`ps ax -Ao ppid | grep $MY_PID | wc -l`))
while [ $JOBS_COUNTER -ge $MAX_CHILDREN ]
do
JOBS_COUNTER=$((`ps ax -Ao ppid | grep $MY_PID | wc -l`))
echo Jobs counter: $JOBS_COUNTER
sleep 1
done
sleep $(($RANDOM % 30)) &
done
echo Finishing children ...
# wait for children here
while [ $JOBS_COUNTER -gt 1 ]
do
JOBS_COUNTER=$((`ps ax -Ao ppid | grep $MY_PID | wc -l`))
echo Jobs counter: $JOBS_COUNTER
sleep 1
done
echo Done
I have 4 important services running on my machine which I want to see them all the time. I have this simple bash script running as bash profile.
echo
PROC="nginx mysql php-fpm pptpd"
for p in $PROC
do
ps cax | grep $p > /dev/null
if [ $? -eq 0 ]; then
echo -e "\e[92m$p running\e[0m"
else
echo -e "\e[101m$p IS NOT RUNNING \e[0m"
fi
done
echo
The out put of this script is:
nginx running
mysql running
php-fpm running
pptpd running
How can I make it like this?
nginx running - mysql running - php-fpm running - pptpd running
Build the status lines first into an array, and then print the array:
status=()
for p in $PROC
do
if ps cax | grep -q $p; then
status+=( " \e[92m$p running\e[0m " )
else
status+=( " \e[101m$p IS NOT RUNNING \e[0m " )
fi
done
(IFS=-; echo -e "${status[*]}")
${status[*]} expands to every element in the array joined by the first character of IFS, which I set to - earlier. Note that I used a subshell (IFS=-; echo ...), so that changing IFS doesn't affect the rest of the script.
Other notes:
ps cax | grep $p > /dev/null
if [ $? -eq 0 ]; then
Can be combined to:
if ps cax | grep -q $p; then
Which is much more concise and readable. You could also consider using pgrep instead.
Use printf or add the -n flag to echo.
POSIX Compliant Refactor without ProcTools
#!/bin/sh
showstatus() {
echo
while [ "$1" ]; do
if ps cax | grep -qF "$1"; then
msg='\e[92m%s running\e[0m'
else
msg='\e[101m%s IS NOT RUNNING \e[0m'
fi
printf "$msg" "$1"
shift
[ "$1" ] && printf ' - '
done
echo
}
showstatus nginx mysql php-fpm pptpd
POSIX Compliant Refactor with ProcTools
#!/bin/sh
showstatus() {
echo
while [ "$1" ]; do
if pkill -0 "$1"; then
msg='\e[92m%s running\e[0m'
else
msg='\e[101m%s IS NOT RUNNING \e[0m'
fi
printf "$msg" "$1"
shift
[ "$1" ] && printf ' - '
done
echo
}
showstatus nginx mysql php-fpm pptpd
Here, I have a shell script named load.sh.
It start my program named "demo" with supervise,
When I run it with sh load.sh start | stop, it works well.
However, when I run it with ./load.sh start | stop, it works bad. the demo is frequently started(and exit) by the supervise.
What's the problem of the two ways of running the shell script?
and is there any problem(bug) in the script cause the supervise frequently restart the demo?
Thanks a lot!
#!/bin/bash
cd `dirname $0` || exit
mkdir -p status/demo
dir_name=`pwd`
STR_LIB=${dir_name}/lib
if [ -z "${LD_LIBRARY_PATH}" ]; then
export LD_LIBRARY_PATH="${STR_LIB}"
else
export LD_LIBRARY_PATH="${STR_LIB}:${LD_LIBRARY_PATH}"
fi
start() {
sleep 1
bin/supervise.demo -u status/demo bin/demo >/dev/null 2>&1 &
}
stop() {
if [ -f status/demo/lock ]; then
supervise_demo_pid=`/sbin/fuser status/demo/lock`
`ps -ef | grep "$supervise_demo_pid" | grep "supervise.demo" | grep -v grep > /dev/null 2>&1`
if [ $? -eq 0 ] && [ "$supervise_demo_pid" != "" ] ; then
echo "kill supervise.demo process:"${supervise_demo_pid}
kill -9 $supervise_demo_pid
fi
fi
if [ -f status/demo/status ]; then
demo_pid=`od -An -j16 -N2 -tu2 status/demo/status`
`ps -ef | grep "$demo_pid" | grep "demo" | grep -v grep > /dev/null 2>&1`
if [ $? -eq 0 ]; then
echo "kill demo process:"${demo_pid}
kill -9 $demo_pid
fi
fi
}
case "$1" in
start)
stop
start
echo "Done!"
;;
stop)
stop
echo "Done!"
;;
*)
echo "Usage: $0 {start|stop}"
;;
esac
sh script.sh runs the script in sh, while running it as ./script.sh uses whatever is specified on its first "shebang" line - /bin/bash in this case.
sh and /bin/bash might be different shells, so they interpret the script differently. What sh is depends on your distribution, $PATH, aliases etc.
When you run your script via ./load.sh start | stop it runs with processor that is specified in shebang. In your case it is bash:
#!/bin/bash
What about sh load.sh start | stop. In Ubuntu (by default) sh is actually just a link and in points to dash.
To check it:
$ which sh
/bin/sh
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Mar 16 00:54 /bin/sh -> dash
sh foo will search $path for an executable foo
sh ./foo demands execution from the $cwd
both
foo and ./foo run via the shebang as noted herein
all forms will invoke foo with the perms of the specific file referenced, including suid,guid
I am trying to check if a process is running with the code below:
SERVICE="./yowsup/yowsup-cli"
RESULT=`ps aux | grep $SERVICE`
if [ "${RESULT:-null}" = null ]; then
echo "not running"
else
echo "running"
fi
But it keeps echoing it is running although it is not. I realized that the grep itself comes as a result and that is the issue.
How can I skip the grep and just check for the process?
Use pgrep:
if pgrep "$SERVICE" >/dev/null 2>&1 ; then
echo "$SERVICE is running"
fi
or:
if pgrep -f "/path/to/$SERVICE" >/dev/null 2>&1 ; then
echo "$SERVICE is running"
fi
NOTE:
pgrep interprets its argument as a regular expression. As a result, paths containing regex characters will likely fail to match or produce false positives (e.g. pgrep -f /home/user/projects/c++/application/executable won't work as expected due to +). This issue can be worked around by escaping the characters in question (e.g. pgrep -f /home/user/projects/c\+\+/application/executable)
pgrep -f <pattern> matches the specified pattern against the whole command line of running processes. As a result, it will match paths appearing as arguments of other processes (e.g. run nano /usr/bin/sleep in one terminal and pgrep -f /usr/bin/sleep in another -> pgrep reports the pid of nano since it contains /usr/bin/sleep as an argument in its command line). To prevent these kind of false positives, prefix the pattern with a caret (^) to force pgrep to only match against the beginning of the command line (e.g. pgrep -f ^/usr/bin/sleep)
For systems where pgrep isn't available you can use:
service="[.]/yowsup/yowsup-cli"
if ps aux | grep -q "$service"; then
echo "not running"
else
echo "running"
fi
[.] in will force grep to not list itself as it won't match [.] regex.
grep -q can be utilized to avoid command substitution step.
Prefer using lowercase variables in shell.
The problem is that grep you call sometimes finds himself in a ps list, so it is good only when you check it interactively:
$ ps -ef | grep bash
...
myaut 19193 2332 0 17:28 pts/11 00:00:00 /bin/bash
myaut 19853 15963 0 19:10 pts/6 00:00:00 grep --color=auto bash
Easiest way to get it is to use pidof. It accepts both full path and executable name:
service="./yowsup/yowsup-cli" # or service="yowsup-cli"
if pidof "$service" >/dev/null; then
echo "not running"
else
echo "running"
fi
There is more powerful version of pidof -- pgrep.
However, if you start your program from a script, you may save it's PID to a file:
service="./yowsup/yowsup-cli"
pidfile="./yowsup/yowsup-cli.pid"
service &
pid=$!
echo $pid > $pidfile
And then check it with pgrep:
if pgrep -F "$pidfile" >/dev/null; then
echo "not running"
else
echo "running"
fi
This is common technique in /etc/init.d start scripts.
The following solution avoids issues with ps + grep, pgrep and pidof (see Advantages below):
# Check if process is running [$1: path to executable]
function is_process_running() {
local path="$1" line
while read -r line; do
[[ "${line}" == "${path}" || "${line}" == "${path} "* ]] && return 0
done < <(ps -e -o command=)
return 1
}
is_process_running "./yowsup/yowsup-cli" && echo "running" || echo "not running"
Explanation:
ps -e -o command= list all processes, only output command line of each process, omit header line
while read -r line; do ... done < <(ps ...) process output produced by ps line by line
[[ "${line}" == "${path}" || "${line}" == "${path} "* ]] check if line matches path exactly -or- path + space + argument(s)
Advantages:
Works for paths containing regex special characters that would trip grep without option -F or pgrep, e.g. /home/user/projects/c++/application/executable (see NOTE in this answer for details)
Avoids issues with ps + grep / pgrep reporting false positives if path appears as argument of some other process (e.g. nano /usr/bin/sleep + pgrep -f /usr/bin/sleep -> falsely reports pid of nano process)
Avoids issues with pidof reporting false positives for processes that are run from PATH (e.g. sleep 60s & + pidof /tmp/sleep -> falsely reports pid of sleep process running from /usr/bin/sleep, regardless of whether /tmp/sleep actually exists or not)
I thought pidof was made for this.
function isrunning()
{
pidof -s "$1" > /dev/null 2>&1
status=$?
if [[ "$status" -eq 0 ]]; then
echo 1
else
echo 0
fi
)
if [[ $(isrunning bash) -eq 1 ]]; then echo "bash is running"; fi
if [[ $(isrunning foo) -eq 1 ]]; then echo "foo is running"; fi
## bash
## function to check if a process is alive and running:
_isRunning() {
ps -o comm= -C "$1" 2>/dev/null | grep -x "$1" >/dev/null 2>&1
}
## example 1: checking if "gedit" is running
if _isRunning gedit; then
echo "gedit is running"
else
echo "gedit is not running"
fi
## example 2: start lxpanel if it is not there
if ! _isRunning lxpanel; then
lxpanel &
fi
## or
_isRunning lxpanel || (lxpanel &)
Note: pgrep -x lxpanel or pidof lxpanel still reports that lxpanel is running even when it is defunct (zombie); so to get alive-and-running process, we need to use ps and grep
current_pid="$$" # get current pid
# Looking for current pid. Don't save lines either grep or current_pid
isRunning=$(ps -fea | grep -i $current_pid | grep -v -e grep -e $current_pid)
# Check if this script is running
if [[ -n "$isRunning" ]]; then
echo "This script is already running."
fi
SERVICE="./yowsup/yowsup-cli"
RESULT=`ps aux | grep $SERVICE|grep -v grep`
if [ "${RESULT:-null}" = null ]; then
echo "not running"
else
echo "running"
fi
I have a shell snippet:
nohup sudo node server.js >> node.log 2>&1 &
if [ $? -eq 0 ]; then
echo $! $?
echo $! > pids
fi
What I expect is if the node server.js run normaly, then record the pid of this process to the file: pids.
But it does'nt work, the $? is always 0 because it is the status of sudo process?
And the $! is also not the pid of the process of node command.
So how can I get the correct return code and pid of the node server.js in the above shell script?
My final solutions:
#!/usr/bin/env bash
ROOT=$(cd `dirname $0`; pwd)
sudo kill -9 `cat ${ROOT}/pids` || true
nohup sudo node server.js >> node.log 2>&1 &
sleep 1
pid=$(ps --ppid $! | tail -1 | awk '{ print $1 }')
if echo $pid | egrep -q '^[0-9]+$'; then
echo $pid > ${ROOT}/pids
else
echo 'server not started!'
fi
When you run a command in the background, there's no sensible way for the shell to get the return code without waiting for the process to finish (i.e., node is no longer running). Therefore even these have return code 0:
$ false &
$ does_not_exist &
It seems what you want to do is to check whether a daemon started properly, which completely depends on the daemon. In your case you've started a Node.js server, so you could simply run something like this (untested):
test_if_server_is_running() {
tries=10
while [ "$tries" -gt 0 ]
do
let tries--
wget http://127.0.0.1/some_server_path && return
sleep 1
done
return 1 # Did not start up in at least 10 seconds
}