如何在 POSIX shell 中使用字符串计算变量?

如何在 POSIX shell 中使用字符串计算变量?

我有一个在 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

相关内容