sh script doesn't work in docker container - bash

I have a problem running a .sh script inside a docker container. It gives me:
ml_1 | 2018-08-02 08:31:32,680 INFO spawned: 'datagrid'
with pid 18
ml_1 | 2018-08-02 08:31:32,686 INFO exited: datagrid
(exit status 127; not expected)
ml_1 | 2018-08-02 08:31:38,732 INFO gave up: datagrid
entered FATAL state, too many start retries too quickly
My script:
#!/bin/bash
# Description:
LIB=/home/com/com_server/lib
CONFIG=/home/com/com_server/config
JAVA="/usr/bin/java"
CLASSPATH=${CONFIG}:blackBoard.xml:${CONFIG}:hazelcastContext.xml:${CONFIG}:comAppConfig.xml:${LIB}:com-calc-0.0.1.jar:${LIB}:com-common-0.0.1.jar:${LIB}:com-hazelcast-0.0.1-jar-with-dependencies.jar:${LIB}:escomled-server-0.0.1.jar:${LIB}:spring-webmvc-4.3.0.RELEASE.jar:${LIB}:spring-jdbc-4.3.0.RELEASE.jar:${LIB}:spring-context-4.3.0.RELEASE.jar:${LIB}:hazelcast-spring-3.7.2.jar:${LIB}:hazelcast-client-3.8.3.jar:${LIB}:hazelcast-spring-3.8.3.jar:${LIB}:hazelcast-all-3.8.3.jar:${LIB}:hazelcast-3.8.3.jar:${LIB}:spring-core-4.3.0.RELEASE.jar:${LIB}:spring-beans-4.3.0.RELEASE.jar:${LIB}:log4j-1.2.16.jar:${LIB}:commons-logging-1.2.jar:${LIB}:spring-asm-4.3.0.RELEASE.jar:${LIB}:spring-expression-4.3.0.RELEASE.jar:${LIB}:mysql-connector-java-5.1.34.jar:${LIB}:spring-tx-4.3.0.RELEASE.jar:${LIB}:commons-lang-2.6.jar:${LIB}:mail-1.4.1.jar:${LIB}:commons-digester-2.0.jar:${LIB}:commons-codec-1.4.jar:${LIB}:slf4j-log4j12-1.5.10.jar:${LIB}:slf4j-api-1.5.10.jar:${LIB}:config/createClient.sql:${LIB}:commons-fileupload-1.2.jar:${LIB}:commons-io-1.4.jar:${LIB}:spring-web-4.3.0.RELEASE.jar:${LIB}:opencsv-2.3.jar:${LIB}:spring-aop-4.3.0.RELEASE.jar:${LIB}:aopalliance-1.0.jar:${LIB}:pdfbox-1.8.9.jar:${LIB}:fontbox-1.8.9.jar:${LIB}:jempbox-1.8.9.jar:${LIB}:imgscalr-lib-4.2.jar:${LIB}:dom4j-1.6.1.jar:${LIB}:xmlbeans-2.6.0.jar:${LIB}:jasypt-1.9.2.jar:${LIB}:jackson-mapper-asl-1.9.4.jar:${LIB}:jackson-core-asl-1.9.4.jar:${LIB}:jackson-jaxrs-1.9.4.jar:${LIB}:cglib-2.2.2.jar:${LIB}:asm-3.3.1.jar:${LIB}:textmagic-java-sdk-1.2.0.jar:${LIB}:httpclient-4.5.5.jar:${LIB}:commons-dbcp2-2.3.0.jar:${LIB}:commons-pool2-2.5.0.jar:${LIB}:poi-3.17.jar:${LIB}:poi-ooxml-3.17.jar:${LIB}:commons-collections4-4.1.jar:${LIB}:poi-ooxml-schemas-3.17.jar
SERVER_NAME="com_datagrid"
SLOG_NAME="com_datagrid"
PID_FILE="/var/run/${SLOG_NAME}.pid"
MEMORY="512";
ARGS="-Djava.awt.headless=true -Xmx1024M -Dcom.sun.management.jmxremote=true \
-Dcom.sun.management.jmxremote.port=9092 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Djava.rmi.server.hostname=10.72.4.13 -Dhazelcast.diagnostics.enabled=true -Dhazelcast.diagnostics.metric.level=info -Dhazelcast.diagnostics.invocation.sample.period.seconds=30 -Dhazelcast.diagnostics.pending.invocations.period.seconds=30 -Dhazelcast.diagnostics.slowoperations.period.seconds=30"
start() {
tput setaf 2;echo "---- STARTING *** com_datagrid *** DAEMON ----"
${JAVA} ${ARGS} -classpath "${CLASSPATH}" com.com.blackboard.main.Server &
javaPID=$!
tput setaf 7;echo "*** com_datagrid *** backgrounded with process id '${javaPID}'"
#echo ${javaPID} > ${PID_FILE}
}
stop() {
echo "STOPING *** com_datagrid ***"
start-stop-daemon --stop \
--pidfile ${PID_FILE}
}
restart() {
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
esac
exit 0;
My Dockerfile:
#FROM maven:3.3.9-jdk-8-alpine as build-env
#COPY . /comML
#WORKDIR comML
#RUN mvn package
FROM openjdk:8-jdk-alpine
WORKDIR /comML
ADD . /comML
ADD ./MLScripts/lib comML/lib
ADD ./MLScripts/config com/config
ADD ./MLScripts/config com/home/com/com_server/config
ADD ./MLScripts comML/MLScripts
ADD target/com-machine-learning-0.0.1-SNAPSHOT-jar-with-dependencies.jar comML/lib/com-machine-learning-0.0.1-SNAPSHOT-jar-with-dependencies.jar
COPY ./MLScripts/wrapper.sh /com/MLScripts/wrapper.sh
#CMD ["export", "CLASSPATH=comML/home/com/com_server/config/blackBoard.xml;EscomledML/home/com/com_server/config/appContext.xml;comML/home/com/com_server/config/config.properties;comML/home/com/com_server/config/com.properties;comML/home/com/escomled_server/config/createClient.sql;EscomledML/home/escomled/escomled_server/config/escomled.properties;com/home/com/com_server/config/global_database.sql;comML/home/com/com_server/config/release.sql;comML/home/escomled/com_server/config/taskExecutors.xml;comML/home/com/com_server/config/test-applicationContext.xml;C:/home/com/com_server/lib/spring-jdbc-4.3.0.RELEASE.jar;C:/home/escomled/escomled_server/lib/escomled-common-0.0.1.jar;C:/home/escomled/escomled_server/lib/escomled-machine-learning-0.0.1-SNAPSHOT-jar-with-dependencies.jar;C:/home/escomled/escomled_server/lib/assertj-core-3.3.0.jar;C:/home/escomled/escomled_server/lib/curator-test-2.9.0.jar;C:/home/escomled/escomled_server/lib/h2o-genmodel-3.18.0.1.jar;C:/home/escomled/escomled_server/lib/hazelcast-all-3.8.3.jar;C:/home/escomled/escomled_server/lib/jcl-over-slf4j-1.7.1.jar;C:/home/escomled/escomled_server/lib/junit-4.12.jar;C:/home/escomled/escomled_server/lib/spring-jdbc-4.3.0.RELEASE.jar;C:/home/escomled/escomled_server/lib/spring-dao-2.0.3.jar;C:/home/escomled/escomled_server/lib/kafka_2.11-0.10.2.1-cp1.jar;C:/home/escomled/escomled_server/lib/kafka_2.11-0.10.2.1-cp1-test.jar;C:/home/escomled/escomled_server/lib/kafka-clients-0.10.2.1-cp1.jar;C:/home/escomled/escomled_server/lib/spring-context-4.3.0.RELEASE.jar;C:/home/escomled/escomled_server/lib/spring-core-4.3.0.RELEASE.jar;C:/home/escomled/escomled_server/lib/spring-tx-4.3.0.RELEASE.jar;C:/home/escomled/escomled_server/lib/hazelcast-all-3.8.3.jar;C:/home/escomled/escomled_server/lib/kafka-clients-0.10.2.1-cp1-test.jar;C:/home/escomled/escomled_server/lib/kafka-schema-registry-3.2.1.jar;C:/home/escomled/escomled_server/lib/kafka-schema-registry-3.2.1-tests.jar;C:/home/escomled/escomled_server/lib/kafka-streams-0.10.2.1-cp1.jar;C:/home/escomled/escomled_server/lib/slf4j-api-1.7.1.jar;C:/home/escomled/escomled_server/lib/slf4j-log4j12-1.7.1.jar"]
#ENTRYPOINT ["java", "-cp", "EscomledML/home/escomled/escomled_server/config/blackBoard.xml;EscomledML/home/escomled/escomled_server/config/appContext.xml;EscomledML/home/escomled/escomled_server/config/config.properties;EscomledML/home/escomled/escomled_server/config/escomled.properties;EscomledML/home/escomled/escomled_server/config/createClient.sql;EscomledML/home/escomled/escomled_server/config/escomled.properties;EscomledML/home/escomled/escomled_server/config/global_database.sql;EscomledML/home/escomled/escomled_server/config/release.sql;EscomledML/home/escomled/escomled_server/config/taskExecutors.xml;EscomledML/home/escomled/escomled_server/config/test-applicationContext.xml;C:/home/escomled/escomled_server/lib/spring-jdbc-4.3.0.RELEASE.jar;C:/home/escomled/escomled_server/lib/escomled-common-0.0.1.jar;C:/home/escomled/escomled_server/lib/escomled-machine-learning-0.0.1-SNAPSHOT-jar-with-dependencies.jar;C:/home/escomled/escomled_server/lib/assertj-core-3.3.0.jar;C:/home/escomled/escomled_server/lib/curator-test-2.9.0.jar;C:/home/escomled/escomled_server/lib/h2o-genmodel-3.18.0.1.jar;C:/home/escomled/escomled_server/lib/hazelcast-all-3.8.3.jar;C:/home/escomled/escomled_server/lib/jcl-over-slf4j-1.7.1.jar;C:/home/escomled/escomled_server/lib/junit-4.12.jar;C:/home/escomled/escomled_server/lib/spring-jdbc-4.3.0.RELEASE.jar;C:/home/escomled/escomled_server/lib/spring-dao-2.0.3.jar;C:/home/escomled/escomled_server/lib/kafka_2.11-0.10.2.1-cp1.jar;C:/home/escomled/escomled_server/lib/kafka_2.11-0.10.2.1-cp1-test.jar;C:/home/escomled/escomled_server/lib/kafka-clients-0.10.2.1-cp1.jar;C:/home/escomled/escomled_server/lib/spring-context-4.3.0.RELEASE.jar;C:/home/escomled/escomled_server/lib/spring-core-4.3.0.RELEASE.jar;C:/home/escomled/escomled_server/lib/spring-tx-4.3.0.RELEASE.jar;C:/home/escomled/escomled_server/lib/hazelcast-all-3.8.3.jar;C:/home/escomled/escomled_server/lib/kafka-clients-0.10.2.1-cp1-test.jar;C:/home/escomled/escomled_server/lib/kafka-schema-registry-3.2.1.jar;C:/home/escomled/escomled_server/lib/kafka-schema-registry-3.2.1-tests.jar;C:/home/escomled/escomled_server/lib/kafka-streams-0.10.2.1-cp1.jar;C:/home/escomled/escomled_server/lib/slf4j-api-1.7.1.jar;C:/home/escomled/escomled_server/lib/slf4j-log4j12-1.7.1.jar", "com.escomled.machinelearning.ml.Escomled_Streams_H2O_ML"]
#CMD ["java", "-jar", "escomled-machine-learning-0.0.1-SNAPSHOT-jar-with-dependencies.jar"]
EXPOSE 8085
#ENTRYPOINT ["sh", "EscomledML/MLScripts/wrapper.sh"]
#ENTRYPOINT ["sh", "EscomledML/MLScripts/escomled_data_grid.sh"]
#CMD ["sh", "EscomledML/MLScripts/escomled_dirwatcher.sh", "&&", "sh", "EscomledML/MLScripts/escomled_startmap.sh", "&&", "sh", "EscomledML/MLScripts/escomled_ml.sh"]
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y supervisor
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
CMD /usr/bin/supervisord -n
And my .bat script:
set LIB=C:/home/escomled/escomled_server/lib
set CONFIG=C:/home/escomled/escomled_server/config
set JAVA_HOME="C:\Program Files\Java\jdk1.8.0_144"
set CLASSPATH=%CONFIG%/blackBoard.xml;%CONFIG%/hazelcastContext.xml;%CONFIG%/escomledAppConfig.xml;%LIB%/escomled-calc-0.0.1.jar;%LIB%/escomled-common-0.0.1.jar;%LIB%/escomled-hazelcast-0.0.1-jar-with-dependencies.jar;%LIB%/escomled-server-0.0.1.jar;%LIB%/spring-webmvc-4.3.0.RELEASE.jar;%LIB%/spring-jdbc-4.3.0.RELEASE.jar;%LIB%/spring-context-4.3.0.RELEASE.jar;%LIB%/hazelcast-spring-3.7.2.jar;%LIB%/hazelcast-client-3.8.3.jar;%LIB%/hazelcast-spring-3.8.3.jar;%LIB%/hazelcast-all-3.8.3.jar;%LIB%/hazelcast-3.8.3.jar;%LIB%/spring-core-4.3.0.RELEASE.jar;%LIB%/spring-beans-4.3.0.RELEASE.jar;%LIB%/log4j-1.2.16.jar;%LIB%/commons-logging-1.2.jar;%LIB%/spring-asm-4.3.0.RELEASE.jar;%LIB%/spring-expression-4.3.0.RELEASE.jar;%LIB%/mysql-connector-java-5.1.34.jar;%LIB%/spring-tx-4.3.0.RELEASE.jar;%LIB%/commons-lang-2.6.jar;%LIB%/mail-1.4.1.jar;%LIB%/commons-digester-2.0.jar;%LIB%/commons-codec-1.4.jar;%LIB%/slf4j-log4j12-1.5.10.jar;%LIB%/slf4j-api-1.5.10.jar;%LIB%/config/createClient.sql;%LIB%/commons-fileupload-1.2.jar;%LIB%/commons-io-1.4.jar;%LIB%/spring-web-4.3.0.RELEASE.jar;%LIB%/opencsv-2.3.jar;%LIB%/spring-aop-4.3.0.RELEASE.jar;%LIB%/aopalliance-1.0.jar;%LIB%/pdfbox-1.8.9.jar;%LIB%/fontbox-1.8.9.jar;%LIB%/jempbox-1.8.9.jar;%LIB%/imgscalr-lib-4.2.jar;%LIB%/dom4j-1.6.1.jar;%LIB%/xmlbeans-2.6.0.jar;%LIB%/jasypt-1.9.2.jar;%LIB%/jackson-mapper-asl-1.9.4.jar;%LIB%/jackson-core-asl-1.9.4.jar;%LIB%/jackson-jaxrs-1.9.4.jar;%LIB%/cglib-2.2.2.jar;%LIB%/asm-3.3.1.jar;%LIB%/textmagic-java-sdk-1.2.0.jar;%LIB%/httpclient-4.5.5.jar;%LIB%/commons-dbcp2-2.3.0.jar;%LIB%/commons-pool2-2.5.0.jar;%LIB%/poi-3.17.jar;%LIB%/poi-ooxml-3.17.jar;%LIB%/commons-collections4-4.1.jar;%LIB%/poi-ooxml-schemas-3.17.jar
set SERVER_NAME="escomled_server"
set SLOG_NAME="escomled_server"
set PID_FILE="/var/run/%SLOG_NAME%.pid"
set MEMORY="512";
set ARGS="-Djava.awt.headless=true -Xmx1024M -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=9092 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=10.72.4.13 -Dhazelcast.diagnostics.enabled=true -Dhazelcast.diagnostics.metric.level=info -Dhazelcast.diagnostics.invocation.sample.period.seconds=30 -Dhazelcast.diagnostics.pending.invocations.period.seconds=30 -Dhazelcast.diagnostics.slowoperations.period.seconds=30"
:start
ECHO "---- STARTING *** DataGrid *** DAEMON ----"
%JAVA_HOME%\bin\java.exe %ARGS% -classpath %CLASSPATH% com.escomled.blackboard.main.DataGridServer
ECHO "*** DataGrid *** backgrounded with process id %javaPID%"
ECHO %javaPID% > %PID_FILE%
EXIT /B 0
:stop
ECHO "STOPING *** DataGrid ***"
start-stop-daemon --stop --pidfile %PID_FILE%
EXIT /B 0
:restart
CALL :stop
CALL :start
rem case "$1" in
rem start)
rem start
rem ;;
rem stop)
rem stop
rem ;;
rem restart)
rem stop
rem start
rem ;;
rem esac
rem exit 0;
I will edit the question if I didn't explain something right. Thank you.

I have a problem running a .sh script inside a docker container
You have a number of issues here... Just some pointers:
Your config file structure is a bit messy, from Dockerfile:
WORKDIR /EscomledML
ADD . /EscomledML
ADD ./MLScripts/lib EscomledML/lib
ADD ./MLScripts/config EscomledML/config
ADD ./MLScripts/config EscomledML/home/escomled/escomled_server/config
ADD ./MLScripts EscomledML/MLScripts
won't really be targeted properly by script since it is expecting it elsewhere:
LIB=/home/escomled/escomled_server/lib
CONFIG=/home/escomled/escomled_server/config
Check all file locations to confirm they are properly placed where they should be.
Daemon should be started in foreground as main process. Since you have issues starting process in the first place, try starting container interactively with /bin/bash and hammer out the starting script properly before setting it as entrypoint of Dockerfile.
You are trying to move from one OS to another. Installation details and environment differences can be the cause of your app not starting properly.
You can use build args and env variables directly with docker to avoid initializing them inside script. Make sure that all env vars are properly initialized
Edit after comment:
You are also having issues with multistage build... Artifacts from previous stage you don't transfer to the last one, effectively dumping them. That's why you don't have any folder after last stage. You need something to the effect of COPY --from=0 ... and also check your desired outcome, since you might be misusing multistage build here (primary intent is to build something in previous layer as disposable build stage, not to combine two images into one).
Edit after next comment:
The way I see it, only thing you are using ubuntu image is to install supervisord. If that is the case, then simply replacing following lines:
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y supervisor
with:
apk add --update supervisor
Will install supervisord in alpine image and you would be good to go.
Note that your directory structure looks quite messed up (you first ADD . then subfolders etc) so make sure to review those things. I have no idea what is your desired directory structure, but you should be able to make head or tails there...

To a first approximation, commands that launch system services or background processes (service, systemctl, initctl, start-stop-daemon, ...) just don't work in Docker.
If you replace all of your script after the initial environment variable setup with the command that runs the actual server in the foreground
#!/bin/sh
LIB=...
...
ARGS=...
exec ${JAVA} ${ARGS} -classpath "${CLASSPATH}" com.escomled.blackboard.main.DataGridServer
The Docker container will stay running until that server process exits, which is what you usually want.

Related

Troubleshooting PM2 Restart in Cron

Update: I was not able to get this working as I desired. I ended up using the pm2 --cron flag since cron couldn't find my pm2 processes.
I am using pm2 restart in a bash script and it always fails on the pm2 restart projectName commands when run by cron (as root) but works when run manually with sudo. I am not sure how to troubleshoot as the pm2 log files don't show anything obvious. It looks like someone else has had the same issue so perhaps it's just a bug? Has anybody else found a way to resolve this issue?
Thank you!
Edit: Adding some context for #kevinnls
Here's the .sh script; I've isolated the command so I can test cron
# Vars
NOW=$(date +"%Y-%m-%d")
LOGS_PATH="/scriptLoc/logs"
LOG_FILE="$LOGS_PATH/$NOW-log.txt"
BE_PATH="/beLoc"
# Start log file
date >> $LOG_FILE
echo "Running..." >> $LOG_FILE
# Temp
cd $BE_PATH
pm2 restart be >> $LOG_FILE
pm2 restart be || echo "ERROR: BE pm2 restart: $?" >> $LOG_FILE
echo "Done." >> $LOG_FILE
exit
If I run the command with sudo ./script.sh it works
If I run it with cron I see the following output in my log file:
Fri Mar 26 17:35:01 UTC 2021
Running...
Use --update-env to update environment variables
ERROR: BE pm2 restart: 1
Done.
If I view pm2 logs:
I see it exit with code 0 and restart when I run the script manually.
I see no output for the failed restart from cron
The error you got:
[PM2][ERROR] Process or Namespace be not found
What is "be"? seems like pm2 from inside of cron has no idea what to make of it.
If it is a file, when you ran the script in your shell, was the file be in your working directory?
You can make these changes to log your error messages to $LOG_FILE.
This should help you get more details.
#redirect output *and* errors to log
pm2 restart be &>> $LOG_FILE
exit_code=$?
# if previous exit code != 0 do everything after `&&'
[[ $exit_code -ne 0 ]] && echo "ERROR: BE pm2 restart: $exit_code" >> $LOG_FILE
Then try running your script again and share the errors encountered.
I was not able to resolve this in the manner I desired. Ultimately I used the -c (cron) flag with pm2 itself.
pm2 cli reference
gitlab issue

Detect if docker ran successfully within the same script

My script.sh:
#/bin/sh
docker run --name foo
(Just assume that the docker command works and the container name is foo. Can't make the actual command public.)
I have a script that runs a docker container. I want to check that it ran successfully and echo the successful running status on the terminal.
How can I accomplish this using the container name? I know that I have to use something like docker inspect but when I try to add that command, it only gets executed after I ^C my script probably because docker has the execution.
In this answer, the docker is executed in some other script so it doesn't really work for my use case.
The linked answer from Jules Olléon works on permanently running services like webservers, application servers, database and similar software. In your example, it seems that you want to run a container on-demand, which is designed to do some work and then exit. Here, the status doesn't help.
When running the container in foreground mode as your example shows, it forwards the applications return code to the calling shell. Since you didn't post any code, I give you a simple example: We create a rc.sh script returning 1 as exit-code (which normally indicates some failure):
#!/bin/sh
echo "Testscript failed, returning exitcode 1"
exit 1
It got copied and executed in this Dockerfile:
FROM alpine:3.7
COPY rc.sh .
ENTRYPOINT [ "sh", "rc.sh" ]
Now we build this image using docker build -t rc-test . and execute a short living container:
$ docker run --rm rc-test
Testscript failed, returning exitcode 1
Bash give us the return code in $?:
$ echo $?
1
So we see that the container failed and could simply check them e.g. inside some bash script with an if-condition to perform some action when it fails:
#!/bin/bash
if ! docker run --rm rc-test; then
echo "Docker container failed with rc $?"
fi
After running your docker run command you can check this way if your docker container is still up and running:
s='^foo$'
status=$(docker ps -qf "name=$s" --format='{{.Status}}')
[[ -n $status ]] && echo "Running: $status" || echo "not running"
You just need to execute it with "-d" to execute the container in detached mode. With this, the solutions provided in the other post or the solution provided by #anubhava are both good solutions.
docker run -d -name some_name mycontainer
s='^some_name$'
status=$(docker ps -qf "name=$s" --format='{{.Status}}')
[[ -n $status ]] && echo "Running: $status" || echo "not running"

How to start a windows process in git-bash with a name

I want to start a java app from git bash in a new window with a process name.
In win cmd it is simple start "appname" java -jar /path/to.jar for example.
But in git bash I get an error The system cannot find the file javaapp
Sidenotes
windows 10 environment
I use git bash as my primary terminal because of the unix commands available there and because of the git repository status visible inside the prompt.
The main reason for naming the process is that I have a shell script that starts multiple java apps, and a shell script to kill them all. For the kill part I need the PID of that process
I followed this great tutorial on springhow.com but in that the process is not started in the new window and if I try to use start it gives the wrong pid (not the pid of the java app) so I tried the solution in this stackoverflow answer but it does not work in bash
If it helps, this is the script (mainly inspired from the link above) to start instances:
#!/bin/bash
#------ DECLARATIONS
app_path=./target/1.0-SNAPSHOT.jar
pidFile=./pid.file
instances=1
#------ BUILD IF NEEDED
if [ ! -f $app_path ];
then
echo Building project...
mvn clean package
else
echo Using existing project build
fi
#------ UPDATING INSTANCES COUNT FROM PARAM IF PRESENT
if [ ! -z "$1" ]; then
instances=$1
fi
echo Starting "$instances" "$app_path" instances
#------ CLEARING PID FILE
> $pidFile
#------ STARTING INSTANCES
for (( i = 0; i < instances; i++ )); do
start java -jar $app_path &
echo $! >> $pidFile
done
echo NOTES:
echo " " Process ids for "$app_path" instances stored in "$pidFile"
echo " " To stop instances type Ctrl+C on each or run stop_multi_apps.sh script that will stop processes with ids from "$pidFile"
You can use cmd for this.
cmd.exe /c start \"appname\" "app"
You do not need & in this case because cmd's start starts does not wait gor it.
If you want to start your program in git bash you could do something like the following:
cmd.exe /c start \"appname\" "C:\path\to\git\bash -c <command>"

Raspberry Pi - Autostart OpenCv-Script - Error with cv::imshow()

Short Description:
I want to auto-start an executable (opencv binary file, generate via c++) via a systemd service-script after booting, but I am unsuccessful.
I narrowed down the error to the code statement "cv::imshow(....)" which opens a window and displays an image. At this point, the code throws the error: "QXcbConnection: Could not connect to display"
However, if I manually execute the sh-script or the binary, both work fine. I searched around stackoverflow for the most common errors, and I tried to fix all I could found. I am quite sure, that:
My service file actually runs at start (until the error occurred)
Manually execution of the binary file works fine
Manually execution of the .sh-script works fine
I do not have runtime-linking errors (see .sh-script)
I would appreciate any help. Please help me fix the error, and please explain to me, why this error even occurs in the first place. Thanks a lot :)
.
My system:
Machine: Raspberry Pi 3 Model B
Architecture: arm32 / ARMv7
OS: NOOBS
.
My script in /etc/systemd/system/ (test.service):
[Unit]
Description=lalala
[Service]
Type=oneshot
ExecStart=/bin/bash "/home/pi/Desktop/test.sh" start
ExecStop=/bin/bash "/home/pi/Desktop/test.sh" stop
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Moreover, I did execute the following commands:
sudo chmod u+rwx /etc/systemd/system/test.service
sudo systemctl enable test
And if I start the service manually, it runs with the same error output as while autostarting during the boot process:
sudo systemctl enable test
.
My shell script (test.sh):
#!/bin/sh -e
exec 2> /tmp/test.sh.log # send stderr to a log file
exec 1>&2 # send stdout to the same log file
set -x # tell sh to display commands before execution
echo "in script"
start()
{
echo "in start"
sleep 30
LD_LIBRARY_PATH=/usr/local/OpenCV/lib:/usr/local/SFML/lib:/usr/local/curl/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
/home/pi/Desktop/test/main -e &
}
# THE OTHER CASES, NOT PUT IN HERE (stop, status)
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart)
stop
start
;;
*)
echo "Usage: {start|stop|status|restart}"
exit 1
;;
esac
exit 0
.
Minimal example of my source code: (executable)
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
int main()
{
cv::Mat frame;
cv::namedWindow("result", cv::WINDOW_NORMAL);
## CRASH
return 0;
}
.
P.S:
I am aware that there is a similar thread like this (Run OpenCV script on start with imshow). But as there is no solution for this question, and as I have more information to share, I thought it would be more appropriate to start a new thread.
Luckily, I solved the problem:
The problem was in the configuration of my serviced-script. I did know that I need a DISPLAY variable to the location of the X Display, but I was not aware of the fact that it needs authorization as well. This thread helped me figure it out:
https://unix.stackexchange.com/questions/85244/setting-display-in-systemd-service-file
In short:
Add these to lines to test.service in /etc/serviced/service:
Environment=XAUTHORITY=/home/pi/.Xauthority
Environment=DISPLAY=:0.0
[Unit]
Description=lalala
[Service]
Type=oneshot
ExecStart=/bin/bash "/home/pi/Desktop/test.sh" start
ExecStop=/bin/bash "/home/pi/Desktop/test.sh" stop
RemainAfterExit=yes
Environment=XAUTHORITY=/home/pi/.Xauthority
Environment=DISPLAY=:0.0
[Install]
WantedBy=multi-user.target
Full code

-bash: cmd: command not found

I have this in /etc/init.d/unicorn
#!/bin/bash
# /etc/init.d/unicorn
# ### BEGIN INIT INFO
# chkconfig: 2345 95 016
# processname: unicorn
# dscription: Stop/start unicorn
### END INIT INFO
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
cmd() {
cd /vagrant
unicorn -p 3000 -D
}
# Start the service
start() {
su - vagrant -c cmd
}
### main logic ###
case "$1" in
start)
start
;;
*)
echo $"Usage: $0 {start}"
exit 1
esac
exit 0
I am trying to start unicorn in my local rails folder. I feel like this command should work:
su - vagrant -c cmd
and cannot figure out the reason.
I guess you are under the impression that the shell function cmd which is defined in that script should be available in the shell which has started that script earlier.
This is wrong, unless you sourced that script (which is unusual for scripts in /etc/init.d/). When you start a script (not source it), then you start a second process which executes the script. All definitions of shell functions (like that cmd) are valid only within that shell script and die with the process.
In case you really want the cmd to be available, you will have to source the script unicorn:
source /etc/init.d/unicorn
The su command, however, will still not be able to call that shell function because it only can call executables it can start using exec(), so they need to be a file. A shell function isn't.
To fix this, inline the function in the shell invoked by su:
start() {
su - vagrant -c 'cd /vagrant && unicorn -p 3000 -D'
}
and as for figuring out the reason in the first place, tooling is helpful:
$ shellcheck unicorn
In unicorn line 19:
su - vagrant -c cmd
^-- SC2033: Shell functions can't be passed to external commands.

Resources