溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Linux中CMD指令怎么用

發(fā)布時(shí)間:2021-11-20 17:22:16 來(lái)源:億速云 閱讀:1305 作者:小新 欄目:云計(jì)算

這篇文章主要為大家展示了“Linux中CMD指令怎么用”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“Linux中CMD指令怎么用”這篇文章吧。

Dockerfile 中只能有一條CMD指令。如果列出多個(gè),CMD 則只有最后一個(gè)CMD會(huì)生效。CMD 主要目的是為運(yùn)行容器時(shí)提供默認(rèn)值。

Docker 不是虛擬機(jī),容器就是進(jìn)程,CMD 指令就是用于指定默認(rèn)的容器主進(jìn)程的啟動(dòng)命令的。在啟動(dòng)(運(yùn)行)一個(gè)容器時(shí)可以指定新的命令來(lái)替代鏡像設(shè)置中的這個(gè)默認(rèn)命令。

可以包含可執(zhí)行文件,當(dāng)然也可以省略。CMD 指令的格式和 RUN 相似,也是兩種格式:

  • shell 格式:CMD <命令>exec 格式:CMD ["可執(zhí)行文件", "參數(shù)1", "參數(shù)2"...]參數(shù)列表格式:CMD ["參數(shù)1", "參數(shù)2"...]。在指定了 ENTRYPOINT 指令后,用 CMD 指定具體的參數(shù)。

注意:不要混淆RUN 和 CMD。RUN實(shí)際上運(yùn)行一個(gè)命令并提交結(jié)果; CMD在構(gòu)建時(shí)不執(zhí)行任何操作,但指定鏡像的默認(rèn)命令。

Linux中CMD指令怎么用

插個(gè)小消息,也方便想學(xué)習(xí)的同學(xué),在文章下方留言即可試聽(tīng)課程外加領(lǐng)取千鋒HTML5、UI交互設(shè)計(jì)、PHP、Java+云數(shù)據(jù)、大數(shù)據(jù)開(kāi)發(fā)、VR/AR/Unity游戲開(kāi)發(fā)、Python人工智能、Linux云計(jì)算、全棧軟件測(cè)試、網(wǎng)絡(luò)安全等全部的視頻學(xué)習(xí)教程。

Docker 不是虛擬機(jī),容器內(nèi)沒(méi)有后臺(tái)服務(wù)的概念。不要期望這樣啟動(dòng)一個(gè)程序到后臺(tái):

CMD systemctl start nginx

這行被 Docker 理解為:

CMD ["sh" "-c" "systemctl start nginx"]

對(duì)于容器而言,其啟動(dòng)程序就是容器的應(yīng)用進(jìn)程,容器就是為了主進(jìn)程而存在的,主進(jìn)程退出,容器就失去了存在的意義,從而退出,其它輔助進(jìn)程不是它需要關(guān)心的東西。

就像上面的示例中,主進(jìn)程是 sh , 那么當(dāng) service nginx start 命令結(jié)束后,sh 也就結(jié)束了,sh 作為主進(jìn)程退出了,自然就會(huì)使容器退出。

Linux中CMD指令怎么用

正確的做法是直接執(zhí)行 nginx 這個(gè)可執(zhí)行文件,并且關(guān)閉后臺(tái)守護(hù)的方式,使程序在前臺(tái)運(yùn)行。

CMD ["nginx", "-g", "daemon off;"]

ENTRYPOINT 指令

ENTRYPOINT 的目的和 CMD 一樣,都是在指定容器的啟動(dòng)程序及參數(shù)。

ENTRYPOINT 在運(yùn)行時(shí)也可以被替代,不過(guò)比 CMD 要略顯繁瑣,需要通過(guò) docker run 的參數(shù) --entrypoint 來(lái)指定。

ENTRYPOINT 的格式和 RUN 指令格式一樣,也分為 exec 格式和 shell 格式。

當(dāng)指定了 ENTRYPOINT 后,CMD 的含義就發(fā)生了改變,不再是直接的運(yùn)行其命令,而是將 CMD 的內(nèi)容作為參數(shù)傳給 ENTRYPOINT 指令,也就是實(shí)際執(zhí)行時(shí),將變?yōu)椋?/p>

<ENTRYPOINT> "<CMD>"

有了 CMD 后,為什么還要有 ENTRYPOINT 呢?

這種 <ENTRYPOINT> "<CMD>" 給我們帶來(lái)了什么好處么?

讓我們來(lái)看幾個(gè)場(chǎng)景。

  • 場(chǎng)景一:讓鏡像變成像命令一樣使用

CMD 方式

FROM centos

RUN yum update \

&& yum install -y curl

CMD [ "curl", "-s", "http://ip.cn" ]

構(gòu)建鏡像后, 運(yùn)行容器

# docker run --rm centos-echo-ip-cmd

執(zhí)行下面命令會(huì)報(bào)錯(cuò)

# docker run --rm centos-echo-ip-cmd -i

我們可以看到報(bào)錯(cuò),executable file not found。之前我們說(shuō)過(guò),跟在鏡像名后面的是 command,運(yùn)行時(shí)會(huì)替換 CMD 的默認(rèn)值。因此這里的 -i 并不是添加在原來(lái)的 curl -s http://ip.cn 后面。 而是替換了原來(lái)的 CMD,變成了 CMD ["-i"],而 -i 根本不是命令,所以報(bào)了可執(zhí)行文件找不到。

所以應(yīng)該使用 ENTRYPOINT 方式

FROM centos

RUN yum install -y curl

ENTRYPOINT ["curl", "-s", "http://ip.cn"]

再次構(gòu)建鏡像后, 運(yùn)行容器

# docker run --rm centos-echo-ip-entrypoint

# docker run --rm centos-echo-ip-entrypoint -i

這樣的話, 最終的指令就變成 ENTRYPOINT ["curl", "-s", "http://ip.cn", "-i"]

  • 場(chǎng)景二:應(yīng)用運(yùn)行前的準(zhǔn)備工作

啟動(dòng)容器就是啟動(dòng)主進(jìn)程,但有些時(shí)候,啟動(dòng)主進(jìn)程前,需要一些準(zhǔn)備工作。

官方鏡像 redis 中的示例:

FROM alpine:3.4

RUN addgroup -S redis && adduser -S -G redis redis

ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 6379

CMD [ "redis-server" ]

可以看到其中為 redis 服務(wù)創(chuàng)建了 redis 用戶,并在最后指定了 ENTRYPOINT 為 docker-entrypoint.sh 腳本。

#!/bin/sh

# allow the container to be started with `--user`

if [ "$1" = 'redis-server' -a "$(id -u)" = '0' ]; then

chown -R redis .

exec gosu redis "$0" "$@"

fi

exec "$@"

該腳本的內(nèi)容就是根據(jù) CMD 的內(nèi)容來(lái)判斷,如果是 redis-server 的話,則切換到 redis 用戶身份啟動(dòng)服務(wù)器,否則依舊使用 root 身份執(zhí)行。比如:

$ docker run -it redis id

uid=0(root) gid=0(root) groups=0(root)

還有 ENTRYPOINT 指令不會(huì)被 RUN 指令覆蓋,而 CMD 指令會(huì)被 RUN 指令覆蓋。

以上是“Linux中CMD指令怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI