用于将 TUI 输入转换为数据库输出的 Bash 脚本无法正常工作

用于将 TUI 输入转换为数据库输出的 Bash 脚本无法正常工作

我有以下 Bash 脚本,它捕获 TUI 数据(zenity)以准备数据库插入语句:

#!/bin/bash

INPUT=NULL,2,Van Tassel,NULL,5,6,,8

INPUT="$(echo $INPUT | ( IFS=, read a b c d e f g h ; echo "$a,${b}xxx,$c,$d,${e}xxx,${f}xxx,${g}}
xxx,${h}xxx" ))"

IFS=,; set -f; set -- $INPUT; out=
for i in "$@"; do
    case "$i" in
        "")    echo empty input not allowed; exit 0;;
        NULL)  out="$out,$i";;
        *xxx)  out="$out,${i/%xxx/}";;
        *)     out="$out,\$\$$i\$\$";;
    esac;
done
echo "${out:1}" 

运行此脚本时我收到以下错误消息:

./err.txt: line 4: Tassel,NULL,5,6,,8: command not found
empty input not allowed

这个脚本有两个问题,我不知道如何解决。首先,只有输入“Van Tassel”或“VanTassel”时,Van Tassel 条目才会起作用,而这并不是从 TUI 界面接收多个字符串的方式。

第二个问题是“”)不起作用。如果我再次运行相同的脚本,但写入 VanTassel 而不是 Van Tassel,我会得到以下输出,而不是消息“不允许空输入”。

NULL,2,$$VanTassel$$,NULL,5,6,,8

事实不应该如此,因为第 7 个字段是空的。

有人可以帮忙吗?

答案1

  1. INPUT=NULL,2,Van Tassel,NULL,5,6,,8就像foo=bar baz:在环境中使用变量运行bazfoobarshell 脚本中,您需要引用或转义空格来抑制此行为。

    对于静态行,引用整个值通常是最好的解决方案:

    INPUT='NULL,2,Van Tassel,NULL,5,6,,8'
    

    在发布的代码中,该行是静态的,但实际上“从 TU 接口接收到多个字符串”,对吗?在这种情况下,解决方案可能取决于这种情况是如何发生的。

  2. 当你声称输出是时NULL,2,$$VanTassel$$,NULL,5,6,,8,它实际上是

    NULL,2,$$VanTassel$$,NULL,5,6,}
    ,8
    

    因为在您的代码中有${g}}一个新队之后就好了。下次发布您正在测试的代码或测试您正在发布的代码。:)

  3. 据称该案例"")不起作用,因为您xxx首先注入了第 7 个字段!以这种方式修改的字段永远不会匹配空字符串;它将匹配*xxx。然后您xxx在构建时删除out,字段将恢复为其原始空值。

  4. echo $INPUT非常脆弱,可能会给你意想不到的结果。Unquoted 的$INPUT行为类似于在这个答案中:发生拆分和文件名生成(通配)。请注意,当我们set -- $INPUT稍后使用时,我们想要拆分,我们抑制了通配符(set -f早些时候)。但您的echo $INPUT容易出现这两种情况。即使您使用echo "$INPUT",这仍然适用:为什么printf比 更好echo在 Bash 中你可以

    IFS=, read … <<<"$INPUT"
    
  5. 使用,read -r除非你知道你不想要-r(参见help read)。

  6. 或许 INPUT应该是input。阅读此文:shell 脚本中变量的命名约定

相关内容