我有一个在 ubuntu 容器内运行的脚本:
#!/bin/sh
name=$(cat < /etc/os-release | grep "^NAME" | cut -d "=" -f 2)
if [ $name = "Ubuntu" ]
then
echo "This should return"
else
echo "This is wrong"
fi
我通过运行启动容器:
docker run -it -v $(pwd):/scripts ubuntu:latest /bin/sh /scripts/test.sh
我收到的输出是“这是错误的”,这是不正确的,因为我知道 $name 的输出是“Ubuntu”,因为我的笔记本电脑是 Ubuntu,但我找不到为什么会出现这种情况的原因脚本中的路线?它在容器外的我的笔记本电脑上执行相同的操作。
答案1
该文件/etc/os-release
包含与 shell 兼容的变量分配列表。您不需要从 shell 脚本中解析它,您只需source
(或.
)它并使用相关变量即可。
$ cat ex.sh
#!/bin/sh
. /etc/os-release
echo "$NAME"
$ ./ex.sh
Ubuntu
答案2
在 Debian 上,该特定行是
NAME="Debian GNU/Linux"
请注意右侧的引号。如果 Ubuntu 上也有它们,那么您也会在 中得到文字引号name
,因为引号对于 来说并不特殊cut
。另一个问题是字符串可能包含空格,在这种情况下,分词会命中 中未加引号的变量扩展[ $name = "Ubuntu" ]
,并且测试可能会出错。
为了避免这些问题,请引用变量扩展,并在比较字符串上添加文字引号:
if [ "$name" = '"Ubuntu"' ]; then ...
或者删除字符串开头和结尾的引号:name=${name#\"}; name=${name%\"}
,并仍然引用"$name"
。
答案3
在这种特殊情况下,您可以简化脚本,如下所示:
#!/bin/sh
if grep -q Ubuntu /etc/os-release; then
echo "This should return"
else
echo "This is wrong"
fi
grep
,当传递该-q
选项时,不会打印任何内容,而是在找到字符串时以代码 0 退出,否则为非零。if
毕竟,这就是我们所期望的。
答案4
简约
$ grep -q Ubuntu /etc/os-release && echo "This should return" || echo "This is wrong"
或者
$ . /etc/os-release && echo "$NAME"
或者你lsb_release
也可以使用命令
$ lsb_release -i -s