【问题标题】:To ask the user to input a date "while" he does not input a date, in bash linux在bash linux中要求用户输入日期“而”他没有输入日期
【发布时间】:2019-10-10 14:51:16
【问题描述】:

我找到了一种方法来检查if 语句的输入是否对应于日期模式和is not a eccentric date

分别:

  • if [[ $dateinput =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]
  • date -d "$dateinput"

他们工作。

我尝试在 while 循环中尽可能地应用它:

dateinput="1992-01-01" #voluntarily made in order to see if the while statement is ok
while [ ! date -d "$dateinput" ]; do
    read -p "Indicate a date please: " Date
    dateinput=$Date
done

结果是它显示提示文本Indicate a date please:,然后显示script.sh: line 73: [[! : command not found,其中第73行是:while [ ! date -d "$dateinput" ]; do。此外,变量dateinput 之后就不再存在,因为它不会显示echo "the input date is: ${dateinput}",而是继续读取并显示脚本的其余行。

我能做些什么来执行它?


bash 版本:4.4.20 |操作系统版本:Ubuntu 18.04.3 LTS。

【问题讨论】:

  • 第 73 行的错误信息和您所说的似乎不一致。但除此之外:如果您检查退出状态(您为date -d 执行此操作),您应该将命令包装在[ ][[ ]]:if ! date -d "$dateinput"; then... 中,可能带有@ 987654335@ 使任何输出静音。
  • 2>&1 比 &> 好,因为我相信后者在 shell 中并不完全支持
  • @Lepr 当然,但如果我知道我使用 Bash 4.4,我喜欢使用方便的速记。该脚本已经使用了一堆 Bashisms(=~ 匹配,read -p)——我可以放心地假设 &> 会起作用。

标签: bash


【解决方案1】:

您可以删除方括号或在日期命令周围添加“$()”,如下所示:

 while [ ! "$(date -d "${dateinput}")" ]; do 
     read -p "Indicate a date please: " dateinput
 done

 while ! date -d "${dateinput}" > /dev/null 2>&1; do
     read -p "Indicate a date please: " dateinput
 done

您不需要> /dev/null 2>&1,但没有它会打印日期输出

【讨论】:

  • 这不处理空的dateinput,但最简单。将&& [[ ! -z ${dateinput} ]] 添加到while 条件中。
  • 我使用了您展示的第一个示例,但稍作修改以编写:while [ ! "$(date -d ${dateinput})" ]; do 但您的解决方案效果很好。但是要使用2>&1/dev/null 会显示错误:line 73: 1/dev/null : ambiguous redirect 并且它不接受有效日期为“1992-01-01”,然后继续循环。第一个解决方案在我制作的 bash 函数中效果很好。非常感谢。
  • 我的愚蠢错误,应该是> /dev/null 2>&1,我会编辑帖子。至于不接受日期,我没有看到日期的问题,希望这只是由于重定向错误
【解决方案2】:
while test -z "$date"; do
    read -p "Indicate a date please: " dateinput;
    if [[ $dateinput =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
        date="$(date -d "$dateinput")";
        if ! test $?; then
            date=""
        fi
    fi
done
echo input date is: "$date"

上面的代码有一个循环在$date 为空时继续运行。循环内的代码提示用户输入日期并读取 $dateinput 。如果用户键入与您的模式匹配的字符串 ([[ $dateinput =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]),那么它将在其上运行 date -d 并将输出保存到 $date。如果date 命令无法识别来自$dateinput 的有效日期(! test $? 将为真),则将$date 设置为空字符串,以便循环再次运行。

当用户输入与您的模式匹配的值并且也是datecommand 的有效日期字符串时,此循环将停止。 date 命令的输出保存在$date 变量中。

一些相关文档:

  1. 对于$?https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html#index-_0024_003f
  2. 对于test 命令https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html#index-test

【讨论】:

  • 感谢您提供此代码 sn-p,它可能会提供一些有限的短期帮助。一个正确的解释would greatly improve 其长期价值,通过展示为什么这是一个很好的解决问题的方法,并将使其对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。
【解决方案3】:

要验证输入是否为日期,您可以执行“日期”,并检查返回代码 - 使用“如果日期 -d”...”。 '[' 允许访问有限的测试运算符集

while true ; do
    read -p "Indicate a date please: " dateinput
    [[ "$dateinput" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] && date -d "$dateInput" >/dev/null && break
done

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    相关资源
    最近更新 更多