之前折腾 GtiHub Actions 想实现提交 issue 后将 issue 的内容生成一个 Markdown 文件提交到仓库,从而实现自动发布到 GitHub Pages 的目的。倒是有一些现成的 Action,但无法完全满足要求,所以自己尝试写一个 wayou/turn-issues-to-posts-action

过程中发现因为 issue 的标题和正文是任意的,也就是以下两部分:

  • github.event.issue.title
  • github.event.issue.body

分别通过环境变量 github.event.issue 获取。

当然,做成 Action 后这些参数通过外面以参数方式传递,因为 Action 里无法获取这些数据。

使用该 Action 的仓库中,.github/workflows/main.yml 配置如下内容进行传递:

...
jobs:
run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: wayou/turn-issues-to-posts-action@v1
with:
dir: "_posts"
title: ${{ github.event.issue.title }}
body: ${{ github.event.issue.body }}
...

里面的内容可能包含任意字符,这样在生成文章标题和正文时会遇到转义问题。

mkdir 创建目录失败的失败

生成的文件默认放到 _posts/ 目录下,但也可以使用的地方进行传递。

mkdir ${{ inputs.dir }}

生成目录过程中,_posts/ 目录不存在的话,该命令会失败,所以需要加上 -p 参数。man mkdir 查看可知:

     -p      Create intermediate directories as required.  If this option is not speci-
fied, the full path prefix of each operand must already exist. On the other
hand, with this option specified, no error will be reported if a directory
given as an operand already exists. Intermediate directories are created
with permission bits of rwxrwxrwx (0777) as modified by the current umask,
plus write and search permission for the owner.

加了该参数后,mkdir 会自动创建缺失的目录而不是直接报错。

标题

然后通过标题创建对应的 Markdown 文件。

touch "${{ inputs.title }}.md"

直接像上面这样肯定不行,因为前面提到,这里的 title 可能包含任意字符。所以需要对 issue 的 title 进行一次处理。

POST_TITLE=$(sed -E 's/[[:space:]|[:punct:]]/_/g' <<<'${{ inputs.title }}')

上述操作是替换掉 issue 标题中的空格及标点。

正文

同时,正文部分也不能直接通过如下方式进行写入:

cat "${{ inputs.body }}" >> "${{ inputs.title }}.md"

一是因为正文是多行文本,这里 Action 执行时会被替换为真实的内容,到时候就是非法的 shell 命令,二是因为正文也会包含任意字符,造成命令非法。

后面发现,可通过如下形式进行文件创建和内容的写入而没有上面这些因为内容而引起的转义问题:

              <<[-]word
here-document
delimiter

可通过 man bash 查看该形式的文档,位于 Here Documents 部分。

调整后文件生成及内容生成部分的命令为

        cat <<'EOF' > _posts/"${DATE:0:10}-${POST_TITLE}".md
---
layout: post
title: "${{ inputs.title }}"
date: ${{ inputs.created_at }}
---
${{ inputs.body }}
EOF

不过仍然需要处理两处转义问题:

  • _posts/"${DATE:0:10}-${POST_TITLE}".md 这里的 "${DATE:0:10}-${POST_TITLE}" 部分需要使用引号包裹,防止我死字符导致的文件名非法
  • title: "${{ inputs.title }}" 这部分位于 Markdown 文件正文部分,会被 jekyll 编译后生成对应的 html 文件,这里不使用引号的话,jekyll 编译会有问题,比如标题中包含 backtick `
---
layout: post
title: `/dev/null`
date: 2020-08-11 23:08:00 +0800
tags:
---

jekyll 报错信息:

Error: YAML Exception reading xxx/_posts/2020-12-25-xxx.md: (<unknown>): found character that cannot start any token while scanning for the next token at line 3 column 8

相关资源

The text was updated successfully, but these errors were encountered:

shell 使用 cat 配合 EOF 创建文件并写入多行内容的更多相关文章

  1. Linux下巧用cat与EOF实现文件的替换和追加

    本文地址http://comexchan.cnblogs.com/,作者Comex Chan,尊重知识产权,转载请注明出处,谢谢! ================================== ...

  2. 【HDFS API编程】查看HDFS文件内容、创建文件并写入内容、更改文件名

    首先,重点重复重复再重复: /** * 使用Java API操作HDFS文件系统 * 关键点: * 1)创建 Configuration * 2)获取 FileSystem * 3)...剩下的就是 ...

  3. python之模块csv之CSV文件的写入(按行写入)

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #CSV文件的写入(按行写入) import csv #csv文件,是一种常用的文本格式,用以存储表格数据,很 ...

  4. rev---将文件中的每行内容以字符为单位反序输出

    rev命令将文件中的每行内容以字符为单位反序输出,即第一个字符最后输出,最后一个字符最先输出,依次类推.

  5. php学习笔记--高级教程--读取文件、创建文件、写入文件

    打开文件:fopen:fopen(filename,mode);//fopen("test.txt","r"): 打开模式:r  仅仅读方式打开,将文件指针指向 ...

  6. java io流 创建文件、写入数据、设置输出位置

    java io流 创建文件 写入数据 改变system.out.print的输出位置 //创建文件 //写入数据 //改变system.out.print的输出位置 import java.io.*; ...

  7. 使用IO流创建文件并写入数据

    /* 字符流和字节流: 字节流两个基类: InputStream OutputStream 字符流两个基类: Reader Writer 既然IO流是用于操作数据的, 那么数据的最常见体现形式是:文件 ...

  8. HDFS上创建文件、写入内容

    1.创建文件 hdfs dfs -touchz /aaa/aa.txt 2.写入内容 echo "<Text to append>" | hdfs dfs -appen ...

  9. Java之创建文件并写入数据

    应用场景:以OJ项目为例,创建对应的.in或.out文件,并将相关的数据写入. 核心代码如下: /** * 创建文件 * @param data * @param basedir * @param n ...

随机推荐

  1. 5分钟入门websocket

    5 个步骤快速掌握消息发送和接收 获取您的 appkey 先注册一个irealtime账号,然后登录到后台管理端,创建一个免费应用,就能得到您的 appkey.点击注册 各种前端生态端集成 ireal ...

  2. Flutter 中不得不会的 mixin

    mixin 是 Dart 中非常重要的概念,对于未接触过此概念的Coder来说尤其重要,最近看源码的时候,由于对 mixin 不熟悉导致理解出现偏差,走了很多弯路,所以这篇文章介绍一下 mixin 概 ...

  3. Dubbo与Zookeeper开发

    1.Dubbo 1.1RPC RPC全称是remote procedure call,即远程过程调用.比如有两台服务器A和B,它们上面分别部署了一个服务.此时B服务器想调用A服务器上提供的方法,由于不 ...

  4. AXU2CGB开发板验证Vitis加速基本平台创建

    Vitis 加速基本平台创建 1.Vivado 工程创建,硬件平台bd 图如下所示 1.1.双击Block图中ZYNQ核,配置相关参数 1.1.1.Low Speed 配置,在 I/O Configu ...

  5. KMP(超详细复杂度分析)

    从 stackoverflow中找到了一个时间复杂度分析很棒的链接 https://www.inf.hs-flensburg.de/lang/algorithmen/pattern/kmpen.htm ...

  6. pip命令安装python包到指定目录

    pip install wxpython --target=D:\Server\Python38\Lib\site-packages

  7. FreeBSD 虚拟网卡 网桥 路由 映射

    网关与路由 netstat -r Routing tables #路由表 Destination Gateway Flags Refs Use Netif Expire 目的地 网关 状态 接口 超时 ...

  8. git配置,以及简单的命令

    在 window 平台需要安装对应的客户端 git 配置全局用户名git config --global user.name "xxx"配置全局邮箱git config --glo ...

  9. android分析之mutex

    Android的锁是对Linux锁的一种包装: // ------------------------------------------------------------------------- ...

  10. Flutter,Weex,React Native比较