我正在尝试制作一个模块化脚本。我有几个脚本/命令,它们从单个脚本调用。
我想为每个单独的命令的输出添加前缀。
例如:
我的文件是所有命令.sh / 命令1.sh / 命令2.sh
命令1.sh输出
file exists
file moved
命令2.sh输出
file copied
file emptied
所有命令运行脚本命令1.sh和命令2.sh
我想给这两个脚本的每个输出添加前缀,如下所示:
[command1] file exists
[command1] file moved
[command2] file copied
[command2] file emptied
答案1
我假设您在 allcommands.sh 中执行的操作是:
command1.sh
command2.sh
只需将其替换为
command1.sh | sed "s/^/[command1] /"
command2.sh | sed "s/^/[command2] /"
答案2
一个最小的例子allcommands.sh
:
#!/bin/bash
for i in command{1,2}.sh; do
./"$i" | sed 's/^/['"${i%.sh}"'] /'
done
使用command1.sh
可执行command2.sh
文件并在同一目录中echo
输入所需的字符串,这将给出 shell 输出:
$ ./command1.sh
file exists
file moved
$ ./command2.sh
file copied
file emptied
$ ./allcommands.sh
[command1] file exists
[command1] file moved
[command2] file copied
[command2] file emptied
快速sed
分解
sed 's/^/['"${i%.sh}"'] /'
s/
进入“正则表达式模式匹配和替换”模式^/
表示“匹配每一行的开头”${i%.sh}
发生在 shell 上下文中,意思是“$i
,但去掉后缀.sh
”['"${i%.sh}"'] /
首先打印一个[
,然后退出引用的上下文以$i
从 shell 中获取变量,然后重新进入以和]
一个空格结束。
答案3
简单示例:
#!/usr/bin/env bash
# allcommands.sh
output-prefix() {
local title="${1/\.[a-zA-Z.0-9-_]*/}"
title="${title/[.-\/_a-zA-Z0-9]*\//}"
"$@" \
2> >(sed "s/^/[$title] [ERR] /" >&2) \
> >(sed "s/^/[$title] [INF] /")
}
output-prefix ./command1.sh
# [command1] [INF] file exists
# [command1] [INF] file moved
output-prefix ./command2.sh
# [command2] [INF] file copied
# [command2] [INF] file emptied
以时间戳作为函数/脚本的前缀:
#!/usr/bin/env bash
output-prefix() {
local title="$1" ; shift
"$@" \
2> >(sed "s/^/$(date '+%Y-%m-%d %H:%M:%S') [ERR] {$title} /" >&2) \
> >(sed "s/^/$(date '+%Y-%m-%d %H:%M:%S') [INF] {$title} /")
}
output-prefix command1 ./command1.sh arg1
# 2023-04-29 17:37:12 [INF] {command1} arg1
# 2023-04-29 17:37:12 [ERR] {command1} test as errout
output-prefix command2 ./command2.sh argB
# 2023-04-29 17:37:12 [INF] {command2} argB
# 2023-04-29 17:37:12 [ERR] {command2} argB as errout