標題幾乎說明了一切(但也許還有更險惡的東西在起作用。)我知道在您登錄/etc/profile.d/*.sh時運行的腳本,但是當您簡單地啟動一個 shell 時,它似乎并沒有按預期作業。以下是 docker 的示例:
創建一個小腳本:
$ echo "echo hello world" > startup.sh
運行安裝腳本的 alpine shell,如下所示:
$ docker run -it --rm -v `pwd`/startup.sh:/etc/profile.d/statup.sh alpine sh
您將得到的只是一個 shell 提示符:
/ #
su -當您從這里開始時,它確實會列印“hello world” :
/ # su -
hello world
2bf679a5677d:~#
但是一個簡單sh的啟動shell是不行的:
/ # sh
/ #
那么,這里有什么問題呢?它是一個不起眼的 Alpine Linux 嗎?它是一個不起眼的 Alpine Linux Docker 鏡像嗎?
uj5u.com熱心網友回復:
DockerfileRUN命令和主容器CMD永遠不會在任何 shell 上、在任何基礎 Linux 發行版上運行任何 shell 點檔案。即使您的基本映像包含 GNU bash 或者您已手動重置SHELL以運行 bash 而不是 standard 也是如此sh。
GNU Bash 參考手冊可能對何時讀取點檔案有最好的描述。有三種情況: shell 可以是非互動式 shell;它可以是互動式 shell,但不能是登錄 shell;或者它可以是專門的登錄外殼。在 Docker 容器中,您遇到的 shell 通常不是互動式 shell,如果是,它們也不是登錄 shell。
對此的重要推論是,在 Dockerfiles 中撰寫 shell 點檔案通常是不正確的。大多數在容器中運行命令的路徑都不會讀取它們。如果您需要設定環境變數,請改用ENV指令。
一些例子:
CMD ["/usr/local/bin/my_program"]
這個exec 表單 CMD根本不運行 shell。沒有sh行程,也不會讀取任何 shell 點檔案。
CMD my_program
# CMD ["/bin/sh", "-c", "my_program"]
這種shell 形式 CMD自動包裝在 中/bin/sh -c '...',但生成的 shell 是非互動式 shell,不讀取點檔案。
docker run --rm my_image my_program
同樣,這不會運行 shell。
docker run --rm my_image sh -c 'my_program'
這顯式地提供了一個 shell 作為命令字串的一部分,但它不是一個互動式 shell。
docker run --rm -it my_image sh
主容器命令是一個shell,你沒有給它一個命令,你已經提供了一個標準輸入;所以在這種情況下,它是一個互動式外殼。如果是 bash,它將讀取.bashrc但不會讀取任何其他點檔案。
docker run --rm -it my_image bash --login
如果您明確請求互動式 shell,它只是一個登錄 shell。幾乎僅在此呼叫中,將讀取完整的 shell 點檔案集。
/etc/profile.d它本身不是標準的外殼功能。這是一些發行版提供的便利,但在 bash 手冊中沒有特別提到。例如比較
docker run --rm ubuntu cat /etc/profile
docker run --rm bash cat /etc/profile
docker run --rm alpine cat /etc/profile
docker run --rm busybox cat /etc/profile
請注意,在前三種情況下,/etc/profile檔案是不同的,但它們都包含讀取/etc/profile.d目錄的邏輯。您的呼叫沒有運行登錄 shell,因此不會讀取該檔案。
在正常情況下,您的容器正在運行的東西不會是外殼。預構建的鏡像就像docker run postgres或是docker run nginx典型的例子:鏡像中打包了一些特定的軟體,運行容器正是運行該單個軟體。啟動 Nginx HTTP 服務器不需要 shell,也不需要讀取 shell 點檔案。
uj5u.com熱心網友回復:
正如在呼叫man ash部分中告訴您的那樣,環境變數可用于在 shell 啟動期間指定要作為源的檔案。這甚至適用于非互動式、非登錄 shell。ENV
在您的 Dockerfile 中:
ENV ENV=/home/youruser/.rc
...然后您的外殼將/home/youruser/.rc在啟動期間執行的內容。
這不是特定的ash行為或高山行為;所有POSIX sh 實作都是如此。(bash 使用BASH_ENV,除非在 sh 兼容模式下運行,此時它也很榮幸ENV)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/512840.html
