如何抑制 bash 脚本中的错误

Poo*_*nam 3 shell-script regular-expression

我试图抑制 date 命令生成的错误,但执行脚本后仍然出现错误。

#!/usr/bin/bash

input="30 FEB 2022"
reg="^[0-9]{1,2}\s[a-zA-Z]{1,3}\s[0-9]{1,4}$"

if [[ $input =~ $reg ]]
then
        echo "VALID Date Format : $input"
        #output=$(`date -d "$input" +"%d-%b-%Y, %A"` 2>&1 > /dev/null)
        output=`date -d "$input" +"%d-%b-%Y, %A"` 2>&1 > /dev/null
else
        echo "INVALID Date Format : $input"
        output="-1"
fi

echo $output
Run Code Online (Sandbox Code Playgroud)

执行后输出 -

root@ip-xx-x-xx-xxx:~# ./exDate.sh 
VALID Date Format : 30 FEB 2022
date: invalid date '30 FEB 2022'
Run Code Online (Sandbox Code Playgroud)

请告知我如何抑制错误?

ter*_*don 8

您已经得到了答案,为您提供了更好的方法,所以我只回答您提出的问题。您仍然看到错误消息的原因是重定向的顺序很重要。重定向是从左到右读取的,因此2>&1 > /dev/null意味着“首先将 stderr 重定向到 stdout,然后将 stdout 重定向到/dev/null”。这意味着您的错误将被打印到标准输出,并且正常的标准输出将被重定向到/dev/null. 您可以通过将 stdout 管道传输到以下命令来看到这一点wc

\n
## No redirection\n$ date -d foo \ndate: invalid date \xe2\x80\x98foo\xe2\x80\x99\n\n## Nothing is printed to stdout, the error goes to stderr\n## and wc has nothing to count\n$ date -d foo | wc\ndate: invalid date \xe2\x80\x98foo\xe2\x80\x99\n      0       0       0\n\n## Redirect using 2>&1 > /dev/null\n$ date -d foo 2>&1 > /dev/null\ndate: invalid date \xe2\x80\x98foo\xe2\x80\x99\n\n## The error is now being printed to stdout, wc counts it\n$ date -d foo 2>&1 > /dev/null | wc\n      1       4      29\n
Run Code Online (Sandbox Code Playgroud)\n

您想要的是将 stdout 重定向到/dev/null第一个,然后将 stderr 重定向到 stdout: > /dev/null 2>&1。这行为如您所愿:

\n
$ date -d foo  > /dev/null 2>&1 \n$ \n
Run Code Online (Sandbox Code Playgroud)\n

  • 由于他们在命令替换中使用“date”,因此他们还需要将重定向移到那里。并且_不_重定向标准输出,因为它需要捕获输出。`output=$(date -d foo 2>/dev/null)` 应该在这种情况下工作。 (2认同)

roa*_*ima 7

您无法使用正则表达式或模式验证日期。(好吧,我想你也许可以这样做,但那会很不愉快。)

\n

相反,使用date命令本身来验证输入。将此脚本写入文件exDate并使其可执行(chmod a+x exDate ):

\n
#!/bin/bash\n\ninput=$1\nif date --date "$input" >/dev/null 2>&1\nthen\n    # Good date\n    output=$(date --date "$input" +'%d-%b-%Y, %A')\nelse\n    # Date parsing failed\n    printf 'INVALID Date Format : %s\\n' "$input" >&2\n    output='-1'\nfi\n\nprintf "%s\\n" "$output"\n
Run Code Online (Sandbox Code Playgroud)\n

运行示例

\n
./exDate '30 FEB 2022'\nINVALID Date Format : 30 FEB 2022\n-1\n\n./exDate '24 FEB 2022'\n24-Feb-2022, Thursday\n\n./exDate '2022-04-13'\n13-Apr-2022, Wednesday\n
Run Code Online (Sandbox Code Playgroud)\n

如果最后一个选项不可接受(即您只想接受表单中的日期d(d) MMM yyyy),那么您需要进行模式匹配以及使用date来验证:

\n
if [[ "$input" =~ ^[0-9]{1,2}\\ [a-zA-Z]{3}\\ [0-9]{4}$ ]] && date\xe2\x80\xa6\nthen\n
Run Code Online (Sandbox Code Playgroud)\n

if date...您可以将与分配合并output=,从而简化代码,然后只需要处理失败情况:

\n
if ! output=$(date --date "$input" +'%d-%b-%Y, %A' 2>/dev/null)\nthen\n    # Date parsing failed\n    printf 'INVALID Date Format : %s\\n' "$input" >&2\n    output='-1'\nfi\n
Run Code Online (Sandbox Code Playgroud)\n