我需要确定任何docker镜像的OS分发名称。我可以将 ubuntu:latest 标记为 image1:latest ,但我应该能够在启动时获取image1:latest的发布信息。
为实现这一目标,我使用下面提到的命令来确定操作系统版本:
$ docker tag ubuntu image1
$
$ docker run -it image1 /bin/sh -c "echo import platform > test.py; echo print\(platform.dist\(\)\) >> test.py; python3 test.py"
('Ubuntu', '14.04', 'trusty')
$
但是,这依赖于图像中是否包含 python2 或 python3 。 ubuntu:12.04失败了,我需要在那里使用python2。
$ docker run -it ubuntu /bin/sh -c "echo import platform > test.py; echo print\(platform.dist\(\)\) >> test.py; python3 test.py"
('Ubuntu', '14.04', 'trusty')
$
$ docker run -it ubuntu:12.04 /bin/sh -c "echo import platform > test.py; echo print\(platform.dist\(\)\) >> test.py; python3 test.py"
/bin/sh: 1: python3: not found
$
$ docker run -it ubuntu:12.04 /bin/sh -c "echo import platform > test.py; echo print\(platform.dist\(\)\) >> test.py; python2 test.py"
('Ubuntu', '12.04', 'precise')
$
Q1。有没有办法在不知道特定图像中哪个版本的python存在的情况下实现同样的目标?
注意:目标是确定用于构建此图像的基本图像。我无法访问用于构建此映像的Dockerfile。
Q2。还有另一种使用入口点的方法。我可以使用Dockerfile从当前图像构建单独的图像。或者,我可以在创建容器时在cmdline中指定入口点,但我需要在容器中访问该脚本。我猜我在使用cmdline时可能需要共享存储,有没有更好的方法来实现这一点?任何指针都会非常有用。
感谢。
答案 0 :(得分:22)
文件系统层次结构标准有一个standard definition for /etc/os-release
,应该可以在大多数发行版上使用:
/ etc / os-release和/ usr / lib / os-release文件包含操作系统标识数据。
os-release的基本文件格式是一个以换行符分隔的类似环境的shell兼容变量赋值列表。可以从shell脚本中获取配置。
这意味着您可以直接来源/etc/os-release
并使用$NAME
或$ID
来识别分发。举个例子,在Fedora上看起来像这样:
% source /etc/os-release
% echo $NAME
Fedora
% echo $ID
fedora
关于Debian:
% source /etc/os-release
% echo $NAME
Debian GNU/Linux
% echo $ID
debian
答案 1 :(得分:2)
您可以将/ etc / issue文件用于Debian / Ubuntu:
int
或/ etc / redhat-release for CentOS / Red Hat / Fedora:
uint
答案 2 :(得分:1)
您应该使用以下cmd来检测 Ubuntu 版本名称:
export UBUNTU_RELEASE=$(lsb_release -sc || cat /etc/*-release|grep -oP 'CODENAME=\K\w+$'|head -1)
对于Ubuntu docker镜像,当我需要将多重智能添加到apt.source.lists并且没有重复行时,我正在使用以下cmds:
RUN export UBUNTU_RELEASE=$(lsb_release -sc || cat /etc/*-release|grep -oP 'CODENAME=\K\w+$'|head -1) &&\
echo "deb http://archive.ubuntu.com/ubuntu/ ${UBUNTU_RELEASE}-security multiverse" >> /etc/apt/sources.list && \
echo "deb-src http://archive.ubuntu.com/ubuntu/ ${UBUNTU_RELEASE}-security multiverse" >> /etc/apt/sources.list && \
echo "deb http://archive.ubuntu.com/ubuntu/ ${UBUNTU_RELEASE} multiverse" >> /etc/apt/sources.list && \
echo "deb-src http://archive.ubuntu.com/ubuntu/ ${UBUNTU_RELEASE} multiverse" >> /etc/apt/sources.list && \
echo "removing duplicated strings from /etc/apt/sources.list" && \
awk '!x[$0]++' /etc/apt/sources.list > /tmp/sources.list && \
cat /tmp/sources.list > /etc/apt/sources.list && \
您应该使用以下cmd来检测 Debian 版本名称(I am using我的泊坞窗图片):
export DEBIAN_RELEASE=$(awk -F'[" ]' '/VERSION=/{print $3}' /etc/os-release | tr -cd '[[:alnum:]]._-' ) && \
[[ "x${DEBIAN_RELEASE}" = "x" ]] && export DEBIAN_RELEASE="unstable"
答案 3 :(得分:1)
在@morxa's answer and comment上展开时,某些sh
尚未定义source
。在这种情况下,我们可以使用
grep NAME /etc/*-release
可以看到什么操作系统。通常PRETTY_NAME
可以说出全名:
PRETTY_NAME="Ubuntu 20.04 LTS"
答案 4 :(得分:1)
大多数答案都给出了操作系统版本,但问题也与docker有关。
我很懒,尤其是当我有超过20张图像时,所以:
import networkx as nx
g = nx.DiGraph()
g.add_edge(1,2, DIRECTIONA="oneway")
g.add_edge(1,3, DIRECTIONA="oneway")
g.add_edge(1,4, DIRECTIONA="bothDirections")
g.add_edge(2,3, DIRECTIONA="bothDirections")
g.add_edge(2,4, DIRECTIONA="oneway")
print(g.edges(data=True))
# [(1, 2, {'DIRECTIONA': 'oneway'}), (1, 3, {'DIRECTIONA': 'oneway'}), (1, 4, {'DIRECTIONA': 'bothDirections'}), (2, 3, {'DIRECTIONA': 'bothDirections'}), (2, 4, {'DIRECTIONA': 'oneway'})]
custom_reversed = nx.DiGraph()
for node_from, node_to, edge_data in list(g.edges(data=True)): # networkx 2.4 doesn not have key parameter
if edge_data['DIRECTIONA'] == 'bothDirections':
custom_reversed.add_edge(node_from, node_to, **edge_data)
print(custom_reversed.edges(data=True))
[(4, 1, {'DIRECTIONA': 'bothDirections'}), (3, 2, {'DIRECTIONA': 'bothDirections'})]
大多数图像都有结果:
docker image ls | perl -lane 'print "docker run --rm $F[0]:$F[1] cat /etc/os-release" unless /REPOSITORY/' | sh | grep PRETTY