我必须处理一个包含crontab指令的给定文件:
##Batch IdRef2Virtuoso
*/1 * * * * /home/batch/autorites/current/bin/exportAutorites2TS.sh > /dev/null 2>&1
*/1 * * * * /home/batch/autorites/current/bin/exportBiblio2TS.sh > /dev/null 2>&1
我想把它剪掉,以便得到一个带有项目列表的yaml文件,然后继续使用ansible。我可以用常规的awk做这样的事情:
while read -r line; do printf '%sn' "$line"| awk '{ split($0, ip, /' '/); printf("- title1: "%s"n title2: "%s"n minute: "%s"n hour: "%s"n day_month: "%s"n month: "%s"n day_week: "%s"n day: "%s"n", ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7], ip[8]);}'; done <"/tmp/crontab-DEV.txt"
结果:
{
"msg": [
{
"day_month": "*",
"day_week": "*",
"hour": "*",
"job": "/home/batch/autorites/current/bin/exportAutorites2TS.sh",
"minute": "*/1",
"month": "*"
},
{
"day_month": "*",
"day_week": "*",
"hour": "*",
"job": "/home/batch/autorites/current/bin/exportBiblio2TS.sh",
"minute": "*/1",
"month": "*"
}
]
}
它可以工作,但它不是很"可靠",我如何才能获得相同的结果?
给定文件
shell> cat crontab
*/1 * * * * /home/batch/autorites/current/bin/exportAutorites2TS.sh > /dev/null 2>&1
*/1 * * * * /home/batch/autorites/current/bin/exportBiblio2TS.sh > /dev/null 2>&1
下面的任务
- command: cat crontab
register: result
- set_fact:
cron_conf: "{{ cron_conf|default([]) + [dict(keys|zip(vals[0:6]))] }}"
loop: "{{ result.stdout_lines }}"
vars:
vals: "{{ item.split() }}"
keys: [minute, hour, day_month, month, day_week, job]
创建列表
cron_conf:
- day_month: '*'
day_week: '*'
hour: '*'
job: /home/batch/autorites/current/bin/exportAutorites2TS.sh
minute: '*/1'
month: '*'
- day_month: '*'
day_week: '*'
hour: '*'
job: /home/batch/autorites/current/bin/exportBiblio2TS.sh
minute: '*/1'
month: '*'
更新09/2022
您可以使用过滤器community.general。字典并避免迭代。例如,下面的声明给出了相同的结果。
cron_keys: [minute, hour, day_month, month, day_week, job]
cron_conf: "{{ result.stdout_lines|
map('split')|
map('zip', cron_keys)|
map('map', 'reverse')|
map('community.general.dict') }}"
这是我在这里提出的一种幼稚的方法,因为它不包括以下情况:
- 有一个6字以上的注释行,例如
# some comment here with six words
- 这个任务实际上比一个"一个词"的表达式要复杂得多。(
/path/to/bin
),如service httpd restart
- 可能还有其他不直接出现在我脑海中的怪癖
说了这么多,你能做的就是使用以下组合:
file
查找以获取文件 的内容- Python方法
str.splitline()
将文件的内容拆分为每行 - Python方法
str.split()
在不同的令牌中分割行 - 然后在任务级使用
vars
来转换字典中的字符串
给定剧本:
- hosts: all
gather_facts: no
tasks:
- set_fact:
cron_expressions: "{{ cron_expressions + [cron_expression] }}"
loop: "{{ lookup('file', '/tmp/crontab-DEV.txt').splitlines() }}"
when: cron_line[5] is defined
vars:
cron_expressions: []
cron_line: "{{ item.split() }}"
cron_expression:
minute: "{{ cron_line[0] }}"
hour: "{{ cron_line[1] }}"
day_month: "{{ cron_line[2] }}"
month: "{{ cron_line[3] }}"
day_week: "{{ cron_line[4] }}"
job: "{{ cron_line[5] }}"
# job: "{{ cron_line[5:] | join('') }}"
# ^-- could be an alternative to recover some possible data loss
# in the job, using an array slice
- debug:
var: cron_expressions
结果是:
PLAY [all] **********************************************************************************************************
TASK [set_fact] *****************************************************************************************************
skipping: [localhost] => (item=## Batch IdRef2Virtuoso)
ok: [localhost] => (item=*/1 * * * * /home/batch/autorites/current/bin/exportAutorites2TS.sh > /dev/null 2>&1)
ok: [localhost] => (item=*/1 * * * * /home/batch/autorites/current/bin/exportBiblio2TS.sh > /dev/null 2>&1)
TASK [debug] ********************************************************************************************************
ok: [localhost] => {
"cron_expressions": [
{
"day_month": "*",
"day_week": "*",
"hour": "*",
"job": "/home/batch/autorites/current/bin/exportAutorites2TS.sh",
"minute": "*/1",
"month": "*"
},
{
"day_month": "*",
"day_week": "*",
"hour": "*",
"job": "/home/batch/autorites/current/bin/exportBiblio2TS.sh",
"minute": "*/1",
"month": "*"
}
]
}
PLAY RECAP **********************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0