Shell脚本使用here文档和变量替换创建repo文件

2017-12-01|Categories: Magedu-training|

here文档形式如下:

cat << token
# ...
# some lines
# ...
token

其中token可以是任意字符,只要保证开始和结束token是同样的内容就可以,常用的token是EOF(End Of File)。

在shell脚本中使用here文档可以快速生成格式化的大段文本,但使用中有一些必须注意的事项,如下代码做了展示:

#!/bin/bash
#
#===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== =====
# Filename:     create-local-yum-repo_by_19_liyang.sh
# Revision:     1.0
# Date:         2017-11-29
# Description:
# Author:       Li Yang
# Website:      https://liyang85.com
#===== ===== ===== ===== ===== ===== ===== ===== ===== ===== ===== =====

repoPath="/etc/yum.repos.d/"
repoFileRegex="^[.[:alnum:]_-]+\.repo$"
disableRepoRegex="^(yes|no)$"

if [ `id -u` -eq 0 ]; then
    read -p "Would you like to disable all exist repoes under ${repoPath}? [yes/no] " disableExistRepoes
    if [[ ${disableExistRepoes} =~ $disableRepoRegex ]]; then
        if [ ${disableExistRepoes} = "yes" ]; then
            cd "${repoPath}"
            repoNum=$(find . -maxdepth 1 -type f -iname "*.repo" | wc -l)
            if [ "${repoNum}" -gt 0 ]; then
                for i in *.repo; do
                    mv -v $i ${i}.bak
                done
                echo "All *.repo files has been renamed to *.repo.bak"
            else
                echo "There is no exist *.repo file."
            fi
        else
            :
        fi
    else
        echo "Your input is invalid. Nothing has been done."
    fi

    echo
    read -p "Please input a repo name (need .repo extension): " repoFile
    if [[ ${repoFile} =~ $repoFileRegex ]]; then
        repoName=`echo ${repoFile} | sed -nr 's/(.+)\.repo$/\1/p'`

        # here文档注意事项:
        #
        # `<<-`会忽略所有的行首空白,
        # `<<`会保留所有的行首空白,
        # 因此,如果 结束token 与行首有空白,将导致语法错误,脚本无法执行
        #
        # `$'...'`这种写法会将转义八进制或十六进制数字转换成ASCII或Unicode字符,
        # `\011`是一个转义八进制数字,表示一个<tab>字符,在here文档中调用时不会被`<<-`忽略
        tab=$'\011'

        # 变量展开替换:可以把变量展开,根据pattern直接替换其中的字符串
        # `${repoName//_/-}`: 把所有下划线(_)替换为中横线(-)
        # `${repoName//[-_]/ }`: 把所有下划线和中横线替换为空格
        cat > "${repoPath}${repoFile}" <<- EOF
        [${repoName//_/-}]
        name=${repoName//[-_]/ }
        baseurl=file:///var/ftp/pub/centos/\$releasever/os/\$basearch
            ${tab}ftp://172.18.19.7/pub/centos/\$releasever/os/\$basearch
        gpgcheck=0
        failovermethod=priority
        EOF

        echo -e "\033[32m${repoFile} has been created.\033[0m\n"
        yum repolist
    else
        echo "${repoFile} is an invalid file name."
        exit 2
    fi
else
    echo "Only root user can run this script."
    exit 1
fi

以上代码将按以下流程执行:

为了测试和对比,首先在/etc/yum.repos.d/新建一个test.repo

然后执行脚本,可以看到test.repo重命名成功,新的repo文件创建成功,yum repolist成功列出了包含的软件包:

实际的文件列表和新的repo文件的内容如下(注意baseurl第二行行首的缩进):

Leave A Comment