我正在尝试为不使用任何文件名运行此 bash 脚本的用户添加使用语句。我想我可以使用“OR”运算符。但剧本还是失败了。
#! /bin/bash
file="$1"
sort -k3,3 -k2,2 -k1 "$1" | awk '{ sum=0; for(i=4; i<=NF; i++){sum+=$i}; sum/=NF-3; print int(sum),"["$1"]",$3",",$2}' || echo "Usage: GradesAwk.sh filename"
这是示例数据。
123456789 Lee Johnson 72 85 90
999999999 Jaime Smith 90 92 91
888111818 JC Forney 100 81 97
290010111 Terry Lee 100 99 100
199144454 Tracey Camp 77 84 84
299226663 Laney Camp 70 74 71
434401929 Skyler Camp 78 81 82
928441032 Jess Forester 85 80 82
928441032 Chris Forester 97 94 89
答案1
由于 pipelinefail 选项(默认情况下禁用),您得到的是典型的 bash 行为。
Bash 手册参考:
管道的返回状态是最后一个命令的退出状态,除非启用了pipefail选项。如果启用了pipefail,则管道的返回状态是最后一个(最右边的)命令以非零状态退出的值,如果所有命令都成功退出,则为零。
在您的情况下,排序命令失败,但 awk 命令不会失败;它只是没有接收到输入,这不是 awk 的失败。
因此,您的||
分支不会执行,因为禁用了 pipelinefail(默认),最后一个管道命令 (awk) 成功了。
您只需将其包含set -o pipefail
在脚本中即可启用 pipelinefail。
检查一下这个测试:
$ ls file7*
file7
$ sort file7 |awk '{print $1}' || echo "error"
abc
four
klm
$ sort file77 |awk '{print $1}' || echo "error"
sort: cannot read: file77: No such file or directory
$ sort file77 2>/dev/null |awk '{print $1}' || echo "error"
$ set -o pipefail
$ sort file77 2>/dev/null |awk '{print $1}' || echo "error"
error
答案2
您希望尽早进行验证:
#!/bin/bash
file="$1"
if [[ -z "$file" ]]; then
echo "Error: no file provided." >&2
echo "usage: $0 file" >&2
exit 1
elif [[ ! -f "$file" ]]; then
echo "Error: no such file '$file'" >&2
exit 2
fi
sort ... "$file" | awk ...