Reputation:
I am creating a Dockerfile
which starts a Java application. This Java application is given a file path which contains the output of ls -l
.
(Note that in my real Dockerfile
I am not doing ls - l
but rather complex commands. I altered that to ls - l
to simplify the question.)
I tried the following:
FROM openjdk:8-jre
ARG JAR
COPY target/$JAR /app/app.jar
CMD java -jar /app/app.jar <( ls -l )
This bash
<( ... )
construction should create a temporary file containing the output of ls -l
.
When starting the Docker file, I get:
/bin/sh: 1: Syntax error: "(" unexpected
Now, sh
does not support the <( ... )
construction, hence the error. How can I start the application safely via bash
instead of sh
? With safely I mean that the Java app still will receive all OS signals (SIGHUP
, ...) and react appropriately.
Upvotes: 1
Views: 100
Reputation: 158748
If you're doing complex things on startup it's often easier to write them into a script than try to build a very complicated command line. Once you're doing that, you can use the set of primitives that are available in the POSIX shell standard, even if they require multiple commands to do things that GNU bash could do inline.
For this I might write a script:
#!/bin/sh
ls -l >/ls-l.txt
exec java -jar /app/app.jar /ls-l.txt
and then copy it in as the default thing your image runs
FROM openjdk:8-jre
ARG JAR
COPY target/$JAR /app/app.jar
COPY launch-app.sh /usr/bin/app
# RUN chmod +x /usr/bin/app, if it's not already executable
CMD ["app"]
Upvotes: 1
Reputation: 295298
Replace your command with a JSON list, for which the first two elements are bash
-c
, and the last element is the shell command you actually want to run.
CMD ["bash", "-c", "exec java -jar /app/app.jar <( ls -l )"]
To generate such an array for a more complex command, you might consider using jq
to ensure that syntax is correct, even for input with backslashes, newlines or quotes:
jq -cnRs '["bash", "-c", input]' <<'EOF'
# you can put other shell commands here if you need to
exec java -jar /app/app.jar <( ls -l )
EOF
exec
ensures that the java
instance replaces bash
, and thus is sent signals directly.
Upvotes: 1