AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / computer / 问题 / 1568168
Accepted
Christian Hick
Christian Hick
Asked: 2020-07-13 15:48:16 +0800 CST2020-07-13 15:48:16 +0800 CST 2020-07-13 15:48:16 +0800 CST

Bash 脚本案例语句,包括未表现的测试条件

  • 772

我有一个有点冗长的脚本(主脚本)。我会把它都包括在这里,因为我相信它可能与答案有关,所以请不要讨厌我。此脚本中的所有内容都有效。我唯一苦苦挣扎的是 case *www1) 和 *www2) 接近尾声,它们基本上是相同的。NULL 测试有效,输入到 Zentiy 框中的数据在这些情况下得到了正确处理。但是,如果我在相应的 Zenity 字段(invoice_number & note)中没有输入任何内容,则会else until [[ -n "${var2}" ]]; do...被忽略。在脚本的末尾,我包含了另一个更简化的脚本,仅针对所讨论的案例(简化)。当我运行它时没有问题,一切都按预期工作。这个案子只是从原件复制过来的,所以我很想知道为什么一个有效,而另一个无效。有人愿意为此提供帮助吗?

主脚本:

#!/bin/bash


work_number="$(zenity --entry --text "ENTER number of work/job entries:" --entry-text "1")"
        a=1

until
        [[ $work_number -lt $a ]]
do

input="$(zenity --forms --title="table work" --text="Add a new job" --separator="," \
       --add-entry="ENTER clientid: " \
       --add-entry="ENTER job_start, -t time without time zone, e.g. '11:45:00', seconds allways zero: " \
       --add-entry="ENTER job_finish, -t time without time zone, e.g. '11:45:00', seconds allways zero: " \
       --add-entry="ENTER number_catchers, -t numeric, must be 0 if no waste has been collected or NULL if it has yet to be assigned to a tip run: " \
       --add-entry="ENTER mower_front, -t numeric:" \
       --add-entry="ENTER mower_back, -t numeric: " \
       --add-entry="ENTER categoryid: " \
       --add-entry="ENTER price, -t numeric: " \
       --add-entry="ENTER invoice_number, -t text: " \
       --add-entry="ENTER note, -t text: " \
       --add-entry="ENTER a tip_runid, -t integer: ")"

psql -tA -U chh1 -d crewdb -c "SELECT SETVAL('work_workid_seq', (SELECT MAX(workid) FROM work), true);" >/dev/null 2>&1
dlink="$(psql -tA -U chh1 -d crewdb -c "SELECT MAX(date_linkid) FROM date_link;")"

startt="$(echo "$input" | awk -F, -v  OFS=, '{print $2}')"
finisht="$(echo "$input" | awk -F, -v  OFS=, '{print $3}')"

st="$( date --date="$startt" +%s  2>/dev/null )"
ft="$( date --date="$finisht" +%s 2>/dev/null )"

if [ -n "$st" -a "$ft" ] ; then

    startt="$(date +%H:%M  -d "$startt"  )"
    finisht="$(date +%H:%M -d "$finisht" )"
    tzdiff="$(( ft - st ))"
else
    tzdiff=0
fi

while [[  ( ( ! "$startt"   =~ ^[0-1][0-9]:[0-5][0-9]$ ) && ( ! "$startt"  =~ ^[0-2][0-3]:[0-5][0-9]$ ) ) ||
          ( ( ! "$finisht"  =~ ^[0-1][0-9]:[0-5][0-9]$ ) && ( ! "$finisht" =~ ^[0-2][0-3]:[0-5][0-9]$ ) ) ||
          ( "$tzdiff" -le 0 )  ]];
do
    var2="$(zenity --forms --title="job start time and/or job finish time are incorrect" --text "Add a job start time and finish_time"  --separator="," \
                   --add-entry="WARNING! Something went wrong. Please enter a valid job start time, e.g. 8:20: " \
                   --add-entry="WARNING! Something went wrong. Please enter a valid job finish time, e.g. 12:30: ")"
    tzdiff=0

    if [ -n "$var2" ] ; then
       b1=$(echo "$var2" | cut -d, -f1 )
       b2=$(echo "$var2" | cut -d, -f2 )

       if [ -n "$b1" -a -n "$b2"  ] ; then
           tz1=$( date --date="$b1" +%s 2>/dev/null )
           tz2=$( date --date="$b2" +%s 2>/dev/null )

           if [ -n "$tz1" -a -n "$tz2" ] ; then
              startt=$(date +%H:%M -d "$b1" )
              finisht=$(date +%H:%M -d "$b2" )
              tzdiff=$(( tz2 - tz1 ))
           fi
       fi
    fi
done

var2="$startt,$finisht"

input="$( echo "$input" | awk -v vard="$dlink" -v vart="$var2" 'BEGIN {  FS="," } { print $1"xxx1" "," vard"ddd" "," vart "," $4"xxx2" "," $5"xxx3" "," $6"xxx4" "," $7"xxx5" "," $8"xxx6" "," $9"www1" "," $10"www2" "," $11"xxx7" ; }' )"

IFS=, read -ra array1 <<<"$input"
out=""

for i in "${array1[@]}"; do

        case "$i" in
        *ddd) out="$out,${i/%ddd/}";;
            
        *xxx1)  if [[ "${i/%xxx1/}" =~ ^[0-9]+$ ]]; then
                
                out="$out,${i/%xxx1/}"

                elif [[ "${i/%xxx1/}" = NULL ]]; then

                    out="$out,${i/%xxx1/}"

                else    until [[ ${var2} =~ ^[0-9]+$ ]] || [[ ${var2} = NULL ]]; do

                                        var2="$(zenity --forms --title="clientid field in table work" --text "Add a clientid"  --separator="," \
                                        --add-entry="WARNING! You either forgot to enter a clientid or didn't enter a number. Please enter a valid clientid: ")"

                                    done

                                    out="$out,${var2}"

                fi  
            
                ;;

        *xxx2) if [[ "${i/%xxx2/}" =~ ^[0-9]+([.][0-9]+)?$ ]]; then

                                out="$out,${i/%xxx2/}"

                                elif [[ "${i/%xxx2/}" = NULL ]]; then

                                        out="$out,${i/%xxx2/}"

                                else    until [[ ${var2} =~ ^[0-9]+([.][0-9]+)?$ ]] || [[ ${var2} = NULL ]]; do

                                        var2="$(zenity --forms --title="number of catchers field in table work" --text "Add number of catchers"  --separator="," \
                                        --add-entry="WARNING! You either forgot to enter number of catchers or didn't enter a number. Please enter a valid number of catchers: ")"

                                        done

                                        out="$out,${var2}"

                                fi

                                ;;

        *xxx3) if [[ "${i/%xxx3/}" =~ ^[0-9]+$ ]]; then

                                out="$out,${i/%xxx3/}"

                                elif [[ "${i/%xxx3/}" = NULL ]]; then

                                        out="$out,${i/%xxx3/}"

                                else    until [[ ${var2} =~ ^[0-9]+$ ]] || [[ ${var2} = NULL ]]; do

                                        var2="$(zenity --forms --title="front mower wheel hight field in table work" --text "Add front mower wheel hight"  --separator="," \
                                        --add-entry="WARNING! You either forgot to enter a front mower wheel hight or didn't enter a number. Please enter a valid front mower wheel hight: ")"

                                        done

                                        out="$out,${var2}"

                                fi

                                ;;

        *xxx4)  if [[ "${i/%xxx4/}" =~ ^[0-9]+$ ]]; then

                                out="$out,${i/%xxx4/}"

                                elif [[ "${i/%xxx4/}" = NULL ]]; then

                                        out="$out,${i/%xxx4/}"

                                else    until [[ ${var2} =~ ^[0-9]+$ ]] || [[ ${var2} = NULL ]]; do

                                        var2="$(zenity --forms --title="back mower wheel hight field in table work" --text "Add back mower wheel hight"  --separator="," \
                                        --add-entry="WARNING! You either forgot to enter a back mower wheel hight or didn't enter a number. Please enter a valid back mower wheel hight: ")"

                                        done

                                        out="$out,${var2}"

                                fi

                                ;;

        *xxx5)  if [[ "${i/%xxx5/}" =~ ^[0-9]+$ ]]; then

                                out="$out,${i/%xxx5/}"

                                elif [[ "${i/%xxx5/}" = NULL ]]; then

                                        out="$out,${i/%xxx5/}"

                                else    until [[ ${var2} =~ ^[0-9]+$ ]] || [[ ${var2} = NULL ]]; do

                                        var2="$(zenity --forms --title="categoryid field in table work" --text "Add a categoryid"  --separator="," \
                                        --add-entry="WARNING! You either forgot to enter a categoryid or didn't enter a number. Please enter a valid categoryid: ")"

                                        done

                                        out="$out,${var2}"

                                fi

                                ;;
            
        *xxx6)  if [[ "${i/%xxx6/}" =~ ^[0-9]+([.][0-9]+)?$ ]]; then

                                out="$out,${i/%xxx6/}"

                                elif [[ "${i/%xxx6/}" = NULL ]]; then

                                        out="$out,${i/%xxx6/}"

                                else    until [[ ${var2} =~ ^[0-9]+([.][0-9]+)?$ ]] || [[ ${var2} = NULL ]]; do

                                        var2="$(zenity --forms --title="price field in table work" --text "Add price"  --separator="," \
                                        --add-entry="WARNING! You either forgot to enter price or didn't enter a number. Please enter a valid price: ")"

                                        done

                                        out="$out,${var2}"

                                fi

                                ;;

        *xxx7)  if [[ "${i/%xxx7/}" =~ ^[0-9]+$ ]]; then

                                out="$out,${i/%xxx7/}"

                                elif [[ "${i/%xxx7/}" = NULL ]]; then

                                        out="$out,${i/%xxx7/}"

                                else    until [[ ${var2} =~ ^[0-9]+$ ]] || [[ ${var2} = NULL ]]; do

                                        var2="$(zenity --forms --title="tip_runid field in table work" --text "Add a tip_runid"  --separator="," \
                                        --add-entry="WARNING! You either forgot to enter a tip_runid or didn't enter a number. Please enter a valid tip_runid: ")"

                                        done

                                        out="$out,${var2}"

                                fi

                                ;;

        *ttt) out="$out,'${i/%ttt/}:00'";;

        *www1)  if [[ "${i/%www1/}" = NULL ]]; then

                out="$out,${i/%www1/}"

                elif [[ -n "${i/%www1/}" ]]; then

                    out="$out,\$\$${i/%www1/}\$\$"

                else    until [[ -n "${var2}" ]]; do

                    var2="$(zenity --forms --title="invoice number field in table work" --text "Add a invoice number"  --separator="," \
                                    --add-entry="WARNING! You either forgot to enter a invoice number. Please enter a invoice number or NULL: ")"

                    if [[ "${var2}" = NULL ]]; then

                        out="$out,${var2}"

                    else

                        out="$out,\$\$${var2}\$\$"

                    fi

                done

                fi
                                ;;

        *www2)  if [[ "${i/%www2/}" = NULL ]]; then

                                out="$out,${i/%www2/}"

                                elif [[ -n "${i/%www2/}" ]]; then

                                        out="$out,\$\$${i/%www2/}\$\$"

                                        else 

                                until [[ -n "${var2}" ]]; do

                                var2="$(zenityi --forms --title="note field in table work" --text "Add a note"  --separator="," \
                                --add-entry="WARNING! You either forgot to enter a note. Please enter a note or NULL: ")"

                                        if [[ "${var2}" = NULL ]]; then

                                                out="$out,${var2}"

                                        else

                                                out="$out,\$\$${var2}\$\$"

                                        fi

                done
                
                fi
                                ;;

        *) out="$out,'${i}:00'";;

esac;
done

echo "${out:1}"

let a++

done

简化脚本:

#!/bin/bash

work_number="$(zenity --entry --text "ENTER number of work/job entries:" --entry-text "1")"
        a=1

until
        [[ $work_number -lt $a ]]
do

input="$(zenity --forms --title="table work" --text="Add a new job" --separator="," \
       --add-entry="ENTER a: " \
       --add-entry="ENTER invoice reference field: " \
       --add-entry="ENTER b: ")"

input="$( echo "$input" | awk 'BEGIN {  FS="," } { print $1 "," $2"www1" "," $3 ; }' )"

IFS=, read -ra myarray <<<"$input"
out=""

for i in "${myarray[@]}"; do
        case "$i" in
        

        *www1) if [[ "${i/%www1/}" = NULL ]]; then

      out="$out,${i/%www1/}"

elif [[ -n "${i/%www1/}" ]]; then

      out="$out,\$\$${i/%www1/}\$\$"

else    until [[ -n "${var2}" ]]; do

            var2="$(zenity --forms --title="invoice number field in table work" --text "Add a invoice number"  --separator="," \
            --add-entry="WARNING! You either forgot to enter a invoice number. Please enter a invoice number or NULL: ")"

                    if [[ "${var2}" = NULL ]]; then

                         out="${var2}"

                    else

                         out="\$\$${var2}\$\$"

                    fi

        done

 fi
 ;;
 esac
done

out="${out#,}"
printf 'out=%s\n' "$out"
echo "$out"

let a++

done

linux bash
  • 1 1 个回答
  • 276 Views

1 个回答

  • Voted
  1. Best Answer
    Kamil Maciorowski
    2020-07-13T16:12:00+08:002020-07-13T16:12:00+08:00

    解释

    您正在重用该var2变量而不取消设置它 ( unset var2) 或为其分配一个空字符串 ( var2='')。因此until [[ -n "${var2}" ]]; do …; done使用一些旧的非空…值,并且永远不会执行代替的代码。

    当您第一次到达时,简化的脚本var2仍然未设置until [[ -n "${var2}" ]]; do。这就是区别。

    每次你写的时候until [[ -n "${var2}" ]]; do问问自己变量的当前值(来自前一个循环左右)是否重要。如果无关紧要,那就让它无关紧要:取消设置之前的变量until。

    另一种方法是在函数中组织代码。在 Bash 的函数中,您可以定义局部变量。局部变量与主脚本中的(如果有的话)或与此或另一个函数的另一个调用var2无关。详情请参阅。例如,如果您创建一个函数并在其中定义,那么您将能够在该函数中使用,而不会有任何其他(旧)干扰的风险。var2var2help localvalidate_invoice_numberlocal var2until [[ -n "${var2}" ]]; dovar2


    例子

    以下代码是从 到 范围内获取两个随机数的有缺陷的0尝试9999。在 Bash$RANDOM中,从0到的范围扩展为一个随机整数。32767我们将继续向 Bash 查询随机数,直到(偶然)我们得到一个满足我们期望的随机数。这类似于您查询用户的方法。这不是从所需范围获取随机整数的最快方法,但在这种情况下,它也没有根本性的缺陷。缺陷在于重用var2,就像在您的代码中一样。到 stderr 的诊断消息可帮助您了解发生的情况。

    #!/bin/bash
    
    for i in 1 2; do
       echo "Loop $i starts. var2 is ${var2:-empty or unset}." >&2
       until [ "$var2" -lt 10000 ] 2>/dev/null; do
          echo "Trying new random number." >&2
          var2="$RANDOM"
       done
       echo "Expectation met. Printing the result." >&2
       echo "$var2"
       echo "Loop $i ends. var2 is ${var2:-empty or unset}." >&2
    done
    

    运行代码,你会看到第二个循环根本没有获得新的随机数。现在让我们尝试unset:

    #!/bin/bash
    
    for i in 1 2; do
       echo "Loop $i starts. var2 is ${var2:-empty or unset}." >&2
       unset var2
       echo "Loop $i continues. var2 is ${var2:-empty or unset}." >&2
       until [ "$var2" -lt 10000 ] 2>/dev/null; do
          echo "Trying new random number." >&2
          var2="$RANDOM"
       done
       echo "Expectation met. Printing the result." >&2
       echo "$var2"
       echo "Loop $i ends. var2 is ${var2:-empty or unset}." >&2
    done
    

    另一种方法是local var2在函数中使用:

    #!/bin/bash
    
    gimme_random () {
       local var2
       echo "Function starts. var2 inside is ${var2:-empty or unset}." >&2
       until [ "$var2" -lt 10000 ] 2>/dev/null; do
          echo "Trying new random number." >&2
          var2="$RANDOM"
       done
       echo "Expectation met. Printing the result." >&2
       echo "$var2"
       echo "Function ends. var2 inside is ${var2:-empty or unset}." >&2
    }
    
    for i in 1 2; do
       echo "Loop $i starts. var2 is ${var2:-empty or unset}." >&2
       gimme_random
       echo "Loop $i ends. var2 is ${var2:-empty or unset}." >&2
    done
    

    This works as expected. The variable inside the function has no connection to the variable outside of the function. When the function is run again, the variable in the new instance is local to the instance.

    Try it without local var2 and it will behave like the first (flawed) snippet. In this case var2 outside of and inside the function (both instances) is the same var2.

    Also note if you run the snippets by just pasting them sequentially in a single shell then var2 (unless local in the function) will remain from one snippet to the other. This will even emphasize the problem.

    • 1

相关问题

  • Notify-发送窗口下出现的通知

  • 以 root 身份运行 docker 容器

  • 如何在域和 Linux 活动目录中启用指纹传感器

  • 如何在CentOS 7 中将Ctrl+C 永久更改为Ctrl+K?

  • 如何从 WSL 打开 office 文件

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何减少“vmmem”进程的消耗?

    • 11 个回答
  • Marko Smith

    从 Microsoft Stream 下载视频

    • 4 个回答
  • Marko Smith

    Google Chrome DevTools 无法解析 SourceMap:chrome-extension

    • 6 个回答
  • Marko Smith

    Windows 照片查看器因为内存不足而无法运行?

    • 5 个回答
  • Marko Smith

    支持结束后如何激活 WindowsXP?

    • 6 个回答
  • Marko Smith

    远程桌面间歇性冻结

    • 7 个回答
  • Marko Smith

    子网掩码 /32 是什么意思?

    • 6 个回答
  • Marko Smith

    鼠标指针在 Windows 中按下的箭头键上移动?

    • 1 个回答
  • Marko Smith

    VirtualBox 无法以 VERR_NEM_VM_CREATE_FAILED 启动

    • 8 个回答
  • Marko Smith

    应用程序不会出现在 MacBook 的摄像头和麦克风隐私设置中

    • 5 个回答
  • Martin Hope
    CiaranWelsh 如何减少“vmmem”进程的消耗? 2020-06-10 02:06:58 +0800 CST
  • Martin Hope
    Jim Windows 10 搜索未加载,显示空白窗口 2020-02-06 03:28:26 +0800 CST
  • Martin Hope
    v15 为什么通过电缆(同轴电缆)的千兆位/秒 Internet 连接不能像光纤一样提供对称速度? 2020-01-25 08:53:31 +0800 CST
  • Martin Hope
    fixer1234 “HTTPS Everywhere”仍然相关吗? 2019-10-27 18:06:25 +0800 CST
  • Martin Hope
    andre_ss6 远程桌面间歇性冻结 2019-09-11 12:56:40 +0800 CST
  • Martin Hope
    Riley Carney 为什么在 URL 后面加一个点会删除登录信息? 2019-08-06 10:59:24 +0800 CST
  • Martin Hope
    zdimension 鼠标指针在 Windows 中按下的箭头键上移动? 2019-08-04 06:39:57 +0800 CST
  • Martin Hope
    jonsca 我所有的 Firefox 附加组件突然被禁用了,我该如何重新启用它们? 2019-05-04 17:58:52 +0800 CST
  • Martin Hope
    MCK 是否可以使用文本创建二维码? 2019-04-02 06:32:14 +0800 CST
  • Martin Hope
    SoniEx2 更改 git init 默认分支名称 2019-04-01 06:16:56 +0800 CST

热门标签

windows-10 linux windows microsoft-excel networking ubuntu worksheet-function bash command-line hard-drive

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve