Return 如果输入不完全是 1 行则出错,否则将输入通过管道传递到下一步
Return an error if input doesn't have exactly 1 line, otherwise pipe input to next step
我有一系列用管道链接在一起的命令:
should_create_one_line | expects_one_line
第一个命令 should_create_one_line
应该产生只有一行的输出,但在奇怪的情况下,输出可能是多行或空的。
我想在这两者之间添加一个步骤,validate_one_line
:
should_create_one_line | validate_one_line | expects_one_line
如果其输入恰好包含 1 行,则 validate_one_line
将简单地输出其输入。如果它的输入包含超过 1 行或为空,那么 validate_one_line
应该导致整个步骤序列停止并且 return 一个错误代码。
我可以为 validate_one_line
使用什么命令?
您可以使用bash脚本来检查传入的数据并在输入只有1行时调用另一个命令
下面的代码开始 cat
当它只出现在 1 行时
sh -c 'while read CMD; do [ ! -z "$LINE" ] && exit 1; LINE=$CMD; done; [ -z "$LINE" ] && exit 1; printf "%s\n" $LINE | "[=10=]" "$@"' cat
这是如何运作的
- 尝试读取一行,如果失败则转到第5步
- 如果变量 $LINE 不为空,转到第 6 步
- 在变量 $LINE 中保存行
- 转到第 1 步
- 如果 $LINE 不为空,转到第 7 步
- 退出状态码为1的程序
- 调用我们的程序并使用
printf
将我们的 $line 传递给它
用法示例:
仅当 grep 找到 1 个匹配项时打印出来:
grep .... | sh -c 'while read CMD; do [ ! -z "$LINE" ] && exit 1; LINE=$CMD; done; [ -z "$LINE" ] && exit 1; printf "%s\n" $LINE | "[=11=]" "$@"' cat
问题张贴者示例:
should_create_one_line | sh -c 'while read CMD; do [ ! -z "$LINE" ] && exit 1; LINE=$CMD; done; [ -z "$LINE" ] && exit 1; printf "%s\n" $LINE | "[=12=]" "$@"' expects_one_line
首先,您应该认真考虑将验证码添加到 expects_one_line
。根据 this post,每个进程都在自己的子 shell 中启动,这意味着即使 validate_one_line
失败,你也会在 expects_one_line
中得到一个错误,因为它会尝试 运行 没有输入(或空行)。也就是说,这里有一个 bash one-liner,您可以将其插入管道以进行验证:
should_create_one_line.sh | ( var="$(cat)"; [ $(echo "$var" | wc -l) -ne 1 ] && exit 1 || echo "$var") | expects_one_line.sh
这里的问题是,当在exit 1
的情况下验证子shell returns 时,expects_one_line.sh
仍然会得到一个空行。如果这对你有用,那就太好了。如果没有,最好将以下内容放入 expects_one_line.sh
:
的开头
input="$(cat)"
[ $(echo "$var" | wc -l) -ne 1 ] && exit 1
这将保证 expects_one_line.sh
在获取单行时正确失败,而不必想知道验证输出的空行将对脚本做什么。
您可能会发现此 post 有帮助:How to read mutliline input from stdin into variable and how to print one out in shell(sh,bash)?
使用read
。这是一个符合您规格的 shell 函数:
exactly_one_line() {
local line # Use to echo the line
read -r line || return # Guarantee at least one line is read
read && return 1 # Indicate failure if another line is successfully read
echo "$line"
}
备注
- "One line" 假定单行后跟换行符。如果您的输入可能是一个包含内容但没有换行符的文件,那么这将失败。
- 给定像
a|b
这样的管道,a
无法阻止 b
来自 运行。至少,当 a
没有输出时,b
需要处理。
演示:
$ wc -l empty oneline twolines
0 empty
1 oneline
2 twolines
3 total
$ exactly_one_line < empty; echo $?
1
$ exactly_one_line < oneline; echo $?
oneline
0
$ exactly_one_line < twolines; echo $?
1
我有一系列用管道链接在一起的命令:
should_create_one_line | expects_one_line
第一个命令 should_create_one_line
应该产生只有一行的输出,但在奇怪的情况下,输出可能是多行或空的。
我想在这两者之间添加一个步骤,validate_one_line
:
should_create_one_line | validate_one_line | expects_one_line
如果其输入恰好包含 1 行,则 validate_one_line
将简单地输出其输入。如果它的输入包含超过 1 行或为空,那么 validate_one_line
应该导致整个步骤序列停止并且 return 一个错误代码。
我可以为 validate_one_line
使用什么命令?
您可以使用bash脚本来检查传入的数据并在输入只有1行时调用另一个命令
下面的代码开始 cat
当它只出现在 1 行时
sh -c 'while read CMD; do [ ! -z "$LINE" ] && exit 1; LINE=$CMD; done; [ -z "$LINE" ] && exit 1; printf "%s\n" $LINE | "[=10=]" "$@"' cat
这是如何运作的
- 尝试读取一行,如果失败则转到第5步
- 如果变量 $LINE 不为空,转到第 6 步
- 在变量 $LINE 中保存行
- 转到第 1 步
- 如果 $LINE 不为空,转到第 7 步
- 退出状态码为1的程序
- 调用我们的程序并使用
printf
将我们的 $line 传递给它
用法示例:
仅当 grep 找到 1 个匹配项时打印出来:
grep .... | sh -c 'while read CMD; do [ ! -z "$LINE" ] && exit 1; LINE=$CMD; done; [ -z "$LINE" ] && exit 1; printf "%s\n" $LINE | "[=11=]" "$@"' cat
问题张贴者示例:
should_create_one_line | sh -c 'while read CMD; do [ ! -z "$LINE" ] && exit 1; LINE=$CMD; done; [ -z "$LINE" ] && exit 1; printf "%s\n" $LINE | "[=12=]" "$@"' expects_one_line
首先,您应该认真考虑将验证码添加到 expects_one_line
。根据 this post,每个进程都在自己的子 shell 中启动,这意味着即使 validate_one_line
失败,你也会在 expects_one_line
中得到一个错误,因为它会尝试 运行 没有输入(或空行)。也就是说,这里有一个 bash one-liner,您可以将其插入管道以进行验证:
should_create_one_line.sh | ( var="$(cat)"; [ $(echo "$var" | wc -l) -ne 1 ] && exit 1 || echo "$var") | expects_one_line.sh
这里的问题是,当在exit 1
的情况下验证子shell returns 时,expects_one_line.sh
仍然会得到一个空行。如果这对你有用,那就太好了。如果没有,最好将以下内容放入 expects_one_line.sh
:
input="$(cat)"
[ $(echo "$var" | wc -l) -ne 1 ] && exit 1
这将保证 expects_one_line.sh
在获取单行时正确失败,而不必想知道验证输出的空行将对脚本做什么。
您可能会发现此 post 有帮助:How to read mutliline input from stdin into variable and how to print one out in shell(sh,bash)?
使用read
。这是一个符合您规格的 shell 函数:
exactly_one_line() {
local line # Use to echo the line
read -r line || return # Guarantee at least one line is read
read && return 1 # Indicate failure if another line is successfully read
echo "$line"
}
备注
- "One line" 假定单行后跟换行符。如果您的输入可能是一个包含内容但没有换行符的文件,那么这将失败。
- 给定像
a|b
这样的管道,a
无法阻止b
来自 运行。至少,当a
没有输出时,b
需要处理。
演示:
$ wc -l empty oneline twolines
0 empty
1 oneline
2 twolines
3 total
$ exactly_one_line < empty; echo $?
1
$ exactly_one_line < oneline; echo $?
oneline
0
$ exactly_one_line < twolines; echo $?
1