我正在尝试从Docker容器运行jython.sh,下面是jython和Java版本
我们真的需要抑制这个错误,这是非常误导性的,看起来很混乱。这个错误在执行对Jython的每次调用之前都会显示,看起来它找不到shell
有没有办法修复下面抛出的错误/异常
如何在docker中让shell对java可见?
使用的命令:
docker run -d <image_name>
docker exec -it <container_name> bash
Dockerfile
FROM alpine:latest
ARG IMAGE_NAME
ENV PATH=$PATH:/bin:/opt/user/jre/bin
ENV LIBRARY_PATH=$LIBRARY_PATH:/opt/user/jre/lib/amd64/server:/opt/user/jre/lib/amd64/jli:/opt/user/jre/lib/amd64
USER user
VOLUME /opt/user/etc/
VOLUME /var/log/user
EXPOSE 6800
ENTRYPOINT ["/bin/bash", "/opt/user/bin/startup.sh", "user"]
#startup.sh script contains some container specific initialization
系统要求
Jython 2.7.1 (default:0df7adb1b397, Jun 30 2017, 19:02:43)
[OpenJDK 64-Bit Server VM (AdoptOpenJDK)] on java1.8.0_292
Type "help", "copyright", "credits" or "license" for more information.
实际结果
$ ./jython.sh
[ERROR] Failed to construct terminal; falling back to unsupported
java.io.IOException: Cannot run program "sh": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at org.python.jline.internal.TerminalLineSettings.exec(TerminalLineSettings.java:308)
at org.python.jline.internal.TerminalLineSettings.stty(TerminalLineSettings.java:282)
at org.python.jline.internal.TerminalLineSettings.get(TerminalLineSettings.java:143)
at org.python.jline.internal.TerminalLineSettings.<init>(TerminalLineSettings.java:108)
at org.python.jline.internal.TerminalLineSettings.getSettings(TerminalLineSettings.java:123)
at org.python.jline.UnixTerminal.<init>(UnixTerminal.java:60)
at org.python.jline.UnixTerminal.<init>(UnixTerminal.java:50)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at org.python.jline.TerminalFactory.getFlavor(TerminalFactory.java:211)
at org.python.jline.TerminalFactory.create(TerminalFactory.java:102)
at org.python.jline.TerminalFactory.get(TerminalFactory.java:186)
at org.python.jline.TerminalFactory.get(TerminalFactory.java:192)
at org.python.jline.console.ConsoleReader.<init>(ConsoleReader.java:243)
at org.python.util.JLineConsole.install(JLineConsole.java:107)
at org.python.core.Py.installConsole(Py.java:1744)
at org.python.core.PySystemState.initConsole(PySystemState.java:1269)
at org.python.core.PySystemState.doInitialize(PySystemState.java:1119)
at org.python.core.PySystemState.initialize(PySystemState.java:1033)
at org.python.core.PySystemState.initialize(PySystemState.java:989)
at org.python.core.PySystemState.initialize(PySystemState.java:984)
at org.python.util.jython.run(jython.java:263)
at org.python.util.jython.main(jython.java:142)
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
at java.lang.ProcessImpl.start(ProcessImpl.java:134)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 26 more
Jython 2.7.1 (default:0df7adb1b397, Jun 30 2017, 19:02:43)
[OpenJDK 64-Bit Server VM (AdoptOpenJDK)] on java1.8.0_292
Type "help", "copyright", "credits" or "license" for more information.
>>>
预期结果
$ ./jython.sh
Jython 2.7.1 (default:0df7adb1b397, Jun 30 2017, 19:02:43)
[OpenJDK 64-Bit Server VM (AdoptOpenJDK)] on java1.8.0_292
Type "help", "copyright", "credits" or "license" for more information.
>>>
工作环境
然而,我能够使用Alpine image&OpenJDK8
Dockerfile
FROM alpine:latest
RUN apk update && apk add --no-cache openjdk8
&& apk add --no-cache bash
bash-5.1$ ./jython.sh
Jython 2.7.1 (default:0df7adb1b397, Jun 30 2017, 19:02:43)
[OpenJDK 64-Bit Server VM (IcedTea)] on java1.8.0_302
Type "help", "copyright", "credits" or "license" for more information.
>>>
Alpine发行版没有bash,而是一个名为ash
的轻量级shell。
从那时起,您有两种可能性,一种是您的脚本足够简单,可以由ash
执行,并且您可以相应地调整shebang和用法,另一种是在Alpine容器中安装bash。
所以,在你的脚本中:
#!/usr/bin/env ash
echo 'I work'
或者,在Dockerfile中
FROM alpine:latest
RUN apk add --no-cache bash
# the rest of your container comes here
如果您的脚本确实将sh
与bash
混淆,那么您还可以通过更改/bin/sh的符号链接来更改/bin/busybox指向的shell,即默认情况下的/bin/sh
FROM alpine:latest
RUN apk add --no-cache bash
&& ln -sf /bin/bash /bin/sh
# the rest of your container comes here
这实际上是你在另一个容器中已经在做的事情,你说它正在工作
FROM alpine:latest
RUN apk update && apk add --no-cache openjdk8
&& apk add --no-cache bash
### ^--- Here you are installing bash
额外注意:安装带有--no-cache
标志的软件包时不需要apk update
值得一读:Alpine Dockerfile的优点--无缓存Vs.rm/var/cache/apk/*