Recursive while loop in docker cmd - bash

I'm trying to run google chrome inside docker containers. I have been able to successfully do so, however there have been instances where chrome would not run on some of the containers (mass creation of containers).
So I'm looking to run a while loop till the chrome process is found to be running. I've tried the following but with errors like "bash: [if: command not found"
var chrome_command = 'google-chrome --user-data-dir=/home/ubuntu/chrome-user-dir';
var cmd = '';
cmd += 'Xvfb :99 & ';
cmd += 'export DISPLAY=:99 & ';
cmd += 'x11vnc -rfbport 6001 -display :99 -bg -q & ';
cmd += 'while [if ps aux | grep "google-chrome"|grep -v grep > /dev/null]; do ' + chrome_command + '; sleep 1 ; done';
Could someone point out where I am going wrong! Thanks!

The last line should be:
cmd += 'while ! ps aux | grep -v grep | grep -q chrome; do ' + chrome_command + '; sleep 1 ; done';
-q for the last grep would suffice to see if there's matched lines in the input.
Use ! to negate the result of list of commands.
It seems google-chrome won't appears in ps aux.

Related

For-Loop strange issue

Please see below outputs, it looks like the first line isn't working for the first file only - but is for the others, any ideas?
#!/bin/sh
cpuser=$1
cd "/home/$cpuser/public_html"
wpconfigs=($(find . -name "wp-config.php"))
for i in "${wpconfigs[#]}";
do
cpuser=$cpuser
wpdb=$(grep -e "DB_NAME" $i | cut -d \' -f 4)
wpuser=$(grep -e "DB_USER" $i | cut -d \' -f 4)
wppass=$(grep -e "DB_PASS" $i | cut -d \' -f 4)
set -x uapi --output=jsonpretty --user="$cpuser" Mysql create_user name="${wpuser}" password="${wppass}";
sleep 2s;
set -x uapi --output=jsonpretty --user="$cpuser" Mysql set_privileges_on_database user="${wpuser}" database="${wpdb}" privileges="ALL PRIVILEGES";
sleep 2s;
set -x uapi --output=jsonpretty --user="$cpuser" Mysql set_password user="${wpuser}" password="${wppass}";
sleep 2s;
done
When I look at the output run set -x to debug I see the following;
[root#cpanel201 ~]# sh ./testing.sh qv5goe35p3783sz8
+ sleep 2s
+ set -x uapi --output=jsonpretty --user=qv5goe35p3783sz8 Mysql set_privileges_on_database 'user=qv5goe35p3783sz8_yscr_bbS$L5' database=qv5goe35p3783sz8_blog 'privileges=ALLPRIVILEGES'
+ sleep 2s
+ set -x uapi --output=jsonpretty --user=qv5goe35p3783sz8 Mysql set_password 'user=qv5goe35p3783sz8_yscr_bbS$L5' password=FhtH6UztIuoS0_
+ sleep 2s
+ for i in "${wpconfigs[#]}"
+ cpuser=qv5goe35p3783sz8
++ grep -e DB_NAME ./wordpress/wp-config.php
++ cut -d \' -f 4
+ wpdb=qv5goe35p3783sz8_wordpress
++ grep -e DB_USER ./wordpress/wp-config.php
++ cut -d \' -f 4
+ wpuser=qv5goe35p3783sz8_yscr_bb5X8h
++ grep -e DB_PASS ./wordpress/wp-config.php
++ cut -d \' -f 4
+ wppass=X7lyC17Td8tH3cm
+ set -x uapi --output=jsonpretty --user=qv5goe35p3783sz8 Mysql create_user name=qv5goe35p3783sz8_yscr_bb5X8h password=X7lyC17Td8tH3cm
+ sleep 2s
+ set -x uapi --output=jsonpretty --user=qv5goe35p3783sz8 Mysql set_privileges_on_database user=qv5goe35p3783sz8_yscr_bb5X8h database=qv5goe35p3783sz8_wordpress 'privileges=ALL PRIVILEGES'
+ sleep 2s
+ set -x uapi --output=jsonpretty --user=qv5goe35p3783sz8 Mysql set_password user=qv5goe35p3783sz8_yscr_bb5X8h password=X7lyC17Td8tH3cm
+ sleep 2s
+ for i in "${wpconfigs[#]}"
+ cpuser=qv5goe35p3783sz8
++ grep -e DB_NAME ./newsite/wp-config.php
++ cut -d \' -f 4
+ wpdb=qv5goe35p3783sz8_newsite
++ grep -e DB_USER ./newsite/wp-config.php
++ cut -d \' -f 4
+ wpuser=qv5goe35p3783sz8_yscr_bbxQiN
++ grep -e DB_PASS ./newsite/wp-config.php
++ cut -d \' -f 4
+ wppass=XpMa4v5z54tcM
+ set -x uapi --output=jsonpretty --user=qv5goe35p3783sz8 Mysql create_user name=qv5goe35p3783sz8_yscr_bbxQiN password=XpMa4v5z54tcM
+ sleep 2s
+ set -x uapi --output=jsonpretty --user=qv5goe35p3783sz8 Mysql set_privileges_on_database user=qv5goe35p3783sz8_yscr_bbxQiN database=qv5goe35p3783sz8_newsite 'privileges=ALL PRIVILEGES'
+ sleep 2s
+ set -x uapi --output=jsonpretty --user=qv5goe35p3783sz8 Mysql set_password user=qv5goe35p3783sz8_yscr_bbxQiN password=XpMa4v5z54tcM
+ sleep 2s
If you look at the outputs for the second + third set of files you'll see three uapi commands, however, for the first we only see two and no outputs in terms of the greps it is doing on the top file.
For your reference, cpuser is set on the command line (the value after sh ./testing.sh)
I've also noticed that in the top file, the user appears to get surrounded by 's however the other two don't.
For clarity what the script is doing here;
Scraping any wp configs for a sql db name, db user and db password
Passing the user name and password to a cpanel api to create the user in a cPanel instance
The action works on config files 2 and 3 in this instance, but, not with the initial one - you will see the first create_user is missing even on the set -x
**
UPDATE
Having reviewed the logs, I believe this may be due to the fact that the user on the first one has a $ within it - could this be why? I have noticed that only on this one also, the command gets quoted within ''s which is incorrect for uapi. If this may be why, how do I resolve that?
'user=qv5goe35p3783sz8_yscr_bbS$L5'
How do I escape the $, as I think that's what is causing the issue in this case - all others are okay, only where a $ is within the username does this issue occur
The follow code tells it all:
$ set -x ls
$ ls
+ ls
a.out
As far as I know in all shells the 'ls' behind 'set -x' is ignored. By the next '$ ls' and '+ ls' you can see that 'set -x' is executed.
The normal way to do this, and probably what you want, is:
$ set -x
$ ls
+ ls
a.out
$ set -
+ set -
Or as a one liner:
$ set -x ; ls ; set -
+ ls
a.out
+ set -
By the previous you can also see why the line is missing in your output 'set -x' just enables shell tracing for the next command, where 'set -' ends it also for the next command.

Running Script on container from host

I've made a script to perform an automate update to PHP service in a container.
At some stage i check if the new PHP version is activated with the following commands:
echo ''| update-alternatives --config php | grep $version | grep auto | head -n 1 | tr -d ' \n\r\t '
the "echo" at the beginning canceling the interactive interaction from the 'update-alternatives' command.
the $version variable is an input from the user(OPTARG) and has a default value if not set.
when im trying to save the command output to a variable , the variable is always set to null after executing the command.
i've tried the following ways:
var=$(echo ''| update-alternatives --config php | grep $version | grep auto | head -n 1 | tr -d ' \n\r\t ')
and:
var=`echo ''| update-alternatives --config php | grep $version | grep auto | head -n 1 | tr -d ' \n\r\t '`
The result of the command when im not redirecting the output to a variable is:
0/usr/bin/php8.181automode
Please help
You need to check the failed command piecemeal.
(Note: my system has only one version of php installed so substituting vi for the example below.)
The command
echo '' | update-alternatives --config vi | grep gtk3 | grep auto
reports
{*} 0 /usr/bin/vim.gtk3 50 auto mode
So ... I suggest that your coding doesn't take into account the format for reporting the choices.
Instead of the tr, use
awk '{ for( i=1 ; i < $NF ; i++){ if( index($i,"/") == 1 ){ print $i ; exit } ; } ; }'

command execute with error when use expect in shell script while work fine in pure shell

I try to start all the exited docker containers deployed in separated servers, so basically i should execute the essential command below
[ $(docker ps -a | grep Exited | wc -l) -ne 0 ] && docker start $(docker ps -a | grep Exited | cut -d' ' -f1)
It worked fine like in pure linux shell , but then error occured(show below) when i try to use expect to "send" the "essential" command. (local ip is 241,remote end is 209)
[root#localhost start_shell_dir]# spawn ssh root#192.168.1.209
root#192.168.1.209's password:
Last login: Fri Oct 15 22:23:25 2021 from 192.168.1.241
[root#localhost ~]# invalid command name "0"
while executing
"0 -ne 0 "
invoked from within
"send "[ 0 -ne 0 ] && docker start ""
The error log shows i have already log in the remote machine, and something wrong when i execute the docker command.
Glenn jackman from the comment area shows me the basic rule for tcl,then i realize expect does command substitutions before sending real command. We may see it from execute bash -x script.sh .
[root#localhost start_shell_dir]# bash -x startContainer.sh
+ read ip pass
+ read ip pass
+ /usr/bin/expect
[root#localhost start_shell_dir]# ++ docker ps -a
++ grep Exited
++ wc -l
++ docker ps -a
++ grep Exited
++ cut '-d ' -f1
spawn ssh root#192.168.1.209
root#192.168.1.209's password:
Last login: Fri Oct 15 22:37:56 2021 from 192.168.1.241
[root#localhost ~]# invalid command name "0"
while executing
"0 -ne 0 "
invoked from within
"send "[ 0 -ne 0 ] && docker start ""
Anyway, the final command that work for me is the command showed below(replace double quotes with braces and with backslash before $() to keep it as an ordinary character rather than pre-parse it).
send {[ \$(docker ps -a | grep Exited | wc -l) -ne 0 ] && docker start \$(docker ps -a | grep Exited | cut -d' ' -f1)}
#!/bin/bash
# my original script with error
while read ip pass
do
{
/usr/bin/expect <<-END
spawn ssh root#$ip
expect {
"yes/no" { send "yes\r";exp_continue }
"password:" { send "$pass\r" }
}
expect "#"
send "[ $(docker ps -a | grep Exited | wc -l) -ne 0 ] && docker start $(docker ps -a | grep Exited | cut -d' ' -f1)"
expect eof
END
}&
done<apps_ip.txt
Like the shell, Tcl (and expect) allows interpolation with double quotes. Tcl uses square brackets for command substitution (in the same way that the shell uses $(...))
Use curly braces to protect the contents of that string (analogous to the shell's single quotes):
send {[ $(docker ps -a | grep Exited | wc -l) -ne 0 ] && docker start $(docker ps -a | grep Exited | cut -d' ' -f1)}
#....^.............................................................................................................^
# and don't forget to hit Enter
send "\r"
See https://www.tcl-lang.org/man/tcl8.6/TclCmd/Tcl.htm for the few syntax rules of Tcl.

2nd echo statement in bash script not working

For some reason I'm not getting the output of my 2nd echo line when I run my script. Here is my code snippet:
IS_RUNNING=$(netstat -anp | grep ":7600" | grep java | awk '{print $7}' | cut -d"/" -f 2)
start(){
nohup /bin/su -c "/opt/app/bin/service start" - user &>/dev/null &
echo "Starting Services please wait"
sleep 30
if [ "$IS_RUNNING" = java ];
then
echo "Service is now running"
exit 0
fi
}
Interestingly. when I run it with:
sh -x ./service start
I get the output expected and my 2nd echo gets written to the screen.
+ case "$1" in
+ start
+ echo 'Starting Services please wait'
Starting Services please wait
+ sleep 30
+ nohup /bin/su -c '/opt/app/bin/service start' - user
+ '[' java = java ']'
+ echo 'Service is now running'
Service is now running
+ exit 0
Without using sh -x, I simply get this:
[root#init.d]# ./service start
Starting Services please wait
[root#init.d]#
I have a feeling I'm overlooking something simple. Can anyone help?
The running line is evaluated once:
IS_RUNNING=$(netstat -anp | grep ":7600" | grep java | awk '{print $7}' | cut -d"/" -f 2)
You should make a function for this or include this line in the start() function after the sleep.

Check if Tomcat is running via shell script

I need to check if Tomcat is running in my system via a shell script. If not I need to catch the process id and kill Tomcat. How shall it be achieved?
in order to get the running process, I've used this command:
ps x | grep [full_path_to_tomcat] | grep -v grep | cut -d ' ' -f 1
You have to be careful, though. It works on my setup, but it may not run everywhere... I have two installations of tomcat, one is /usr/local/tomcat on port 8080 and /usr/local/tomcat_8081 on port 8081. I have to use '/usr/local/tomcat/' (with the final slash) as the full_path because otherwise it would return 2 different pids if tomcat_8081 is running as well.
Here's the explanation of what this command does:
1) ps x gives you a list of running processes ordered by pid, tty, stat, time running and command.
2) Applying grep [full_path_to_tomcat] to it will find the pattern [full_path_to_tomcat] within that list. For instance, running ps x | grep /usr/local/tomcat/ might get you the following:
13277 ? Sl 7:13 /usr/local/java/bin/java -Djava.util.logging.config.fil
e=/usr/local/tomcat/conf/logging.properties [...] -Dcatalina.home=/usr/local/tomca
t [...]
21149 pts/0 S+ 0:00 grep /usr/local/tomcat/
3) As we get 2 entries instead of one due to the grep /usr/local/tomcat/ matching the pattern, let's remove it. -v is the invert-match flag for grep, meaning it will select only lines that do not match the pattern. So, in the previous example, using ps -x | grep /usr/local/tomcat/ | grep -v grep will return:
13277 ? Sl 7:13 /usr/local/java/bin/java -Djava.util.logging.config.fil
e=/usr/local/tomcat/conf/logging.properties [...] -Dcatalina.home=/usr/local/tomca
t [...]
4) Cool, now we have the pid we need. Still, we need to strip all the rest. In order to do that, let's use cut. This command removes sections from a FILE or a standard output. The -d option is the delimiter and the -f is the field you need. Great. So we can use a space (' ') as a delimiter, and get the first field, which corresponds to the pid. Running ps x | grep /usr/local/tomcat/ | grep -v grep | cut -d ' ' -f 1 will return:
13277
Which is what you need. To use it in your script, it's simple:
#replace below with your tomcat path
tomcat_path=/users/tomcat/apache-tomcat-8.0.30
pid=$(ps x | grep "${tomcat_path}" | grep -v grep | cut -d ' ' -f 1)
if [ "${pid}" ]; then
eval "kill ${pid}"
fi
One way to check by using wget for your server address and checking the status.
Check this link here :
http://www.velvettools.com/2013/07/shell-script-to-check-tomcat-status-and.html#.VX_jfVz-X1E
TOMCAT_HOME=/usr/local/tomcat-folder/
is_Running ()
{
wget -O - http://yourserver.com/ >& /dev/null
if( test $? -eq 0 ) then
return 0
else
return 1
fi
}
stop_Tomcat ()
{
echo "shutting down......"
$TOMCAT_HOME/bin/shutdown.sh
}
start_Tomcat ()
{
echo "starting......"
$TOMCAT_HOME/bin/startup.sh
}
restart ()
{
stop_Tomcat
sleep 10
kill_Hanged_Processes
start_Tomcat
sleep 60
}
the easy way to do that is :
ps -ef | grep tomcat
by using this command you'll get :
user [id-to-kill] Date [tomcat-path]
last step is killing the process
sudo kill -9 [id-to-kill]
Congratulation, your process was killed lOol
Tomcat's default port is 8080. u can grep it and use port status in comparision loop.
#!/bin/bash
STAT=`netstat -na | grep 8080 | awk '{print $7}'`
if [ "$STAT" = "LISTEN" ]; then
echo "DEFAULT TOMCAT PORT IS LISTENING, SO ITS OK"
elif [ "$STAT" = "" ]; then
echo "8080 PORT IS NOT IN USE SO TOMCAT IS NOT WORKING"
## only if you defined CATALINA_HOME in JAVA ENV ##
cd $CATALINA_HOME/bin
./startup.sh
fi
RESULT=`netstat -na | grep 8080 | awk '{print $7}' | wc -l`
if [ "$RESULT" = 0 ]; then
echo "TOMCAT PORT STILL NOT LISTENING"
elif [ "$RESULT" != 0 ]; then
echo "TOMCAT PORT IS LISTENINS AND SO TOMCAT WORKING"
fi
this way you can compare the script.you grep port 8080 if you are using the default port for tomcat.this will only check whether tomcat is running.
then you can check the processes using the port
lsof -i:8080 //if using port 8080
the if you want to free the port by killing the process using it use this command
kill 75782 //if for instance 75782 is the process using the port

Resources