使用子shell重写坏替换

时间:2017-01-17 12:34:55

标签: bash parameter-expansion

我试图在没有引号的情况下获取发行版名称。

cat /etc/*-release | grep "NAME=.*" -o | cut -d "=" -f2 | head -n1

返回: "CentOS Linux"

现在,使用shell替换,我试图删除引号将命令放在子shell中:

echo ${$(cat /etc/*-release | grep "NAME=.*" -o | cut -d "=" -f2 | head -n1)/\"}

我以为我可以使用\"转义引号然后省略最后/来删除引号。

编辑: 我知道这可以用awk完成,但我不知道如何。

编辑: 输出cat /etc/*-release

CentOS Linux release 7.2.1511 (Core)
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

CentOS Linux release 7.2.1511 (Core)
CentOS Linux release 7.2.1511 (Core)

预期输出:CentOS Linux

3 个答案:

答案 0 :(得分:2)

/etc/os-release似乎是一组简单的shell赋值语句;你可能只是简单地获取它并输出$NAME的值(使用子shell来避免可能覆盖当前shell中的任何变量):

( . /etc/os-release; echo "$NAME" )

这可能存在安全风险,具体取决于/etc/os-release因任何原因可能包含其他可执行代码的信任级别。

根据您的实际需要,您也可以简单地使用/etc/centos-release,其中包含您想要的信息作为简单字符串。 (当然,您可能不会假设您的脚本将在CentOS框上运行。os-release似乎是一个更不依赖于发行版的版本。)

答案 1 :(得分:1)

使用awk,在NAME变量后面获取操作系统名称。

awk -F"=" '$1=="NAME"{gsub(/"/, "", $2);print $2; exit}' /etc/os-release 
CentOS Linux

答案 2 :(得分:0)

您的解决方案几乎可行。 "CentOS Linux"中的引号是发布文件的一部分,使用子shell没有帮助。您可以将cut与双引号一起用作分隔符:

cat /etc/*-release | grep "NAME=.*" -o | cut -d "=" -f2 | head -n1 | cut -d '"' -f2

您可以使用sed

进行相同操作
sed -n '/^NAME=/ {s/NAME="\(.*\)".*/\1/p;q}' /etc/*-release 

说明:告诉sed仅打印p要求的行,查找以NAME=开头的行,匹配引号之间的部分,并在第一行之后退出NAME=