• shell模板变量替换


    我们经常使用一些模板语言来处理一些变量替换。比如jsp,php,velocity,freemarker,thymeleaf等。那对于shell来说,应该怎样替换变量呢。有一种很简单的办法可以做到。

    先来看一个应用场景。在datax是阿里开源的一个异构数据源同步框架,其配置文档是json的,我想要用shell去调用执行pg到pg的数据同步,需要根据我的配置生成对应的配置文件。这如果用java来做就是维护一个对象,设置value,最后json-encode就好了。要是使用shell,这样也可以做到:

    渲染脚本

    #!/bin/bash
    
    SRC_USER_NAME=etl
    SRC_USER_PWD=etl
    SRC_SQL="select * from tab"
    SRC_HOST_IP="192.168.1.1"
    SRC_HOST_PORT=3306
    SRC_DB="abc_db"
    TAR_USER_NAME="etl2"
    TAR_USER_PWD="pass2"
    fields_map=""a","b","c""
    TAR_HOST_IP="aaaadfsdfdsfjsdjf"
    TAR_HOST_PORT="5432"
    TAR_DB="tar_db"
    TAR_TABLENAME="tbname"
    eval "cat <<EOF
    $(< pg2pg.datax.json)
    EOF
    "  > result.json
    

    模板文档
    pg2pg.datax.json

    {
        "job": {
            "setting": {
                "speed": {
                    "byte": 1048576
                },
                "errorLimit": {
                    "record": 0,
                    "percentage": 0.02
                }
            },
            "content": [
                {
                    "reader": {
                        "name": "postgresqlreader",
                        "parameter": {
                            "username": "${SRC_USER_NAME}",
                            "password": "${SRC_USER_PWD}",
                            "where": "",
                            "connection": [
                                {
                                    "querySql": [
                                        "${SRC_SQL}"
                                    ],
                                    "jdbcUrl": [
                                        "jdbc:postgresql://${SRC_HOST_IP}:${SRC_HOST_PORT}/${SRC_DB}"
                                    ]
                                }
                            ]
                        }
                    },
                    "writer": {
                    
                        "name": "postgresqlwriter",
                        "parameter": {
                            "username": "${TAR_USER_NAME}",
                            "password": "${TAR_USER_PWD}",
                            "column": [
                                ${fields_map}
                            ],
                            "preSql": [
                                ""
                            ],
                            "connection": [
                                {
                                    "jdbcUrl":  "jdbc:postgresql://${TAR_HOST_IP}:${TAR_HOST_PORT}/${TAR_DB}",
                                    "table": [
                                        "${TAR_TABLENAME}"
                                    ]
                                }
                            ]
                        }
                    }
                }
            ]
        }
    }
    

    输出结果

    {
        "job": {
            "setting": {
                "speed": {
                    "byte": 1048576
                },
                "errorLimit": {
                    "record": 0,
                    "percentage": 0.02
                }
            },
            "content": [
                {
                    "reader": {
                        "name": "postgresqlreader",
                        "parameter": {
                            "username": "etl",
                            "password": "etl",
                            "where": "",
                            "connection": [
                                {
                                    "querySql": [
                                        "select * from tab"
                                    ],
                                    "jdbcUrl": [
                                        "jdbc:postgresql://192.168.1.1:3306/abc_db"
                                    ]
                                }
                            ]
                        }
                    },
                    "writer": {
                    
                        "name": "postgresqlwriter",
                        "parameter": {
                            "username": "etl2",
                            "password": "pass2",
                            "column": [
                                "a","b","c"
                            ],
                            "preSql": [
                                ""
                            ],
                            "connection": [
                                {
                                    "jdbcUrl":  "jdbc:postgresql://aaaadfsdfdsfjsdjf:5432/tar_db",
                                    "table": [
                                        "tbname"
                                    ]
                                }
                            ]
                        }
                    }
                }
            ]
        }
    }
    

    核心内容是

    eval "cat <<EOF
    $(< pg2pg.datax.json)
    EOF
    "  > result.json
    

    其中有几个语法需要学习下。

    第一shell中变量的定义,变量赋值时,等号(=)`两边必须没有空格。

    第二, eval的用法。

    语法:eval cmdLine

    eval会对后面的cmdLine进行两遍扫描,如果第一遍扫描替换变量,然后执行cmdLine.

    [etl@data-server001 test]$ set 11 22 33 44
    [etl@data-server001 test]$ echo $4
    44
    [etl@data-server001 test]$ echo $#
    4
    [etl@data-server001 test]$ echo "$$#"
    $4
    [etl@data-server001 test]$ eval echo "$$#"
    44
    

    本组测试中,echo可以读取变量的第一层定义,所以$#代表参数个数4,$4代表第4个参数44。但我们想要直接取最后一个参数,需要使用变量的值作为变量的value。eval就会再次扫描一遍。

    第三,cat <<EOF 这是一个多行输入的操作。

    [etl@data-server001 test]$ cat <<EOF
    > aaa
    > bbb
    > ccc
    > EOF
    aaa
    bbb
    ccc
    

    EOF代表End Of File,这里表示输入结束标志,<<EOF表示定义结束符为EOF,接下来直到输入EOF时,命令结束。cat就会把内容输出。cat本来是输出文件内容的,这里把输入当做临时文件处理了。

    第四, $(xxx) 表示执行命令,和两个反引号的效果相同,会执行里面的命令。所以< pg2pg.datax.json 才会读取文件内容。

    最后输入EOF结束内容。需要注意EOF前后不要有空格,必须是回车,不然就不代表最后一个字符了。

    为了更加容易理解,可以修改渲染脚本

    content=$(cat pg2pg.datax.json)
    eval "cat <<EOF
    $content
    EOF"  > result.json
    
    1. eval替换$content的值
  • 相关阅读:
    不知道搜索引擎对display:none和visibility:hidden是怎么个看法
    《Effective C#中文版:改善C#程序的50种方法》前言
    SEO实践之网站内部结构设计优化
    友情提示:职场修炼,参加招聘会注意事项
    CSS命名规范
    发布两款纯CSS编写的下拉菜单已测IE6,7,8,FF均可运行
    解读2010年中国九大SEO新星工作室
    南通SEO爱好者之“拿来主义”!
    轻松一刻——幽默
    大学生进行职业选择要有市场意识
  • 原文地址:https://www.cnblogs.com/woshimrf/p/shell-template-variable.html
Copyright © 2020-2023  润新知