shell - shell 中的方括号(测试条件)内容和高级案例陈述

标签 shell testing if-statement case conditional-statements

我有两个问题。让我们先讨论更简单的一个,然后再讨论 case 语句。 考虑这个简单的 if else

if  fgrep -q '= ' sf
then
echo "blanks in file"
else
echo "no blanks"
fi

[[ `fgrep -q '= ' sf` ]]  && echo "blanks there"
# rc=$?
# echo "rc is $rc"

if 条件就像一个魅力。我正在尝试使用 [[ 测试条件重写相同的内容,但它并不完全有效。我的测试条件有什么问题。

现在是第二个问题

实际上这就是我想要做的。

我有这种案例陈述

    source "/path"
    # die is a function that will output standard error and return 1 
    opta=false
    optb=false

while getopts ":abf:" opt; do
  case $opt in
      a ) $optb && die "Cannot specify option a after specifying option b"
          opta=true
          ;;
      b ) $opta && die "Cannot specify option b after specifying option a"
          optb=true
          ;;
      f) # Pl see the note below for f 

      \?) die "Invalid option: -$OPTARG. Abort"
          ;;
  esac
done
shift $(($OPTIND - 1))
test $# -eq 0 && die "You must supply SID"
test $# -eq 1 || die "Too many command-line arguments"
SID=$1

f 是一个文件选项。因此,如果使用 -f,则前两个不兼容。

myshell -f /path/file1 -a 500 

以上是不允许的。我可以管理这部分所以不要太担心

这就是让我偏离道路的障碍。 -f 接受文件路径。该文件是一个手动覆盖文件,其中包含各种参数,这些参数将覆盖使用 source 命令设置的参数。因此,当谈到 f 选项时,它应该执行以下操作 检查是否

  1. 文件路径有效

  2. 2.

如果有效,检查是否有“=”即。等于后跟空白 - 然后退出。换句话说,我不想要空白值 ||那些^空白的

3

如果满足这两个条件,则如果在文件中设置了搜索字符串 s 参数,则不能将任何位置参数传递给命令。

例如下面的手动覆盖文件

p1=v1
p2=v2
s=v3
p3=


     # some parameters like p3 need to be set in that case it will take the defaults from   the source file  if those aren't set 

换句话说,例如下面的命令

myshell.ksh -f/path/file1 500

如果 s 的值未在 file1 中设置则有效,否则它应该退出并给出一个错误,即当覆盖值已在文件 -f file1 中应用时提供了位置参数

4 将 file1 中设置的所有参数导出为对源文件参数的覆盖。 例如源文件有

  p1=sv1

然后在文件 1 中设置 p1 然后从文件 1 中导出 p1=v1

我可以管理#4。我最多只需要了解 3 美元。 2,1 和 4 不会造成伤害

最佳答案

问题一

[[...]] 在那里没有任何业务。使用:

fgrep -q '= ' sf && echo "blanks there"

上面的代码在 sf 上运行了 fgrep。如果 fgrep 指示成功,则运行 echo 命令。

问题2

如果/path/file1 包含s 变量的设置并且命令行上有位置参数,那么我们应该报告错误:

grep '^s=' /path/file1 && [ "$#" -gt 0 ] && echo "ERROR: file has s parameter set and there are positional arguments"

上面检查两个条件是否为真,如果它们都为真,它会打印一条错误消息。第一个条件是:

grep '^s=' /path/file1

如果文件 /path/file1 有一行以字符 s= 开头,则为真。 (^表示一行的开始。)第二个条件是:

[ "$#" -gt 0 ]

如果位置参数的数量大于零,则返回真。如果这两个条件都为真,则执行上面的 echo 语句。

问题 2:替代方法

在这种情况下,我们假设变量$filepath有文件的路径和名称,比如/path/file1,里面包含了用于设置的shell命令变量。以下检查该文件是否可读。如果是,那么它将获取该文件中的所有命令。下一行检查是否设置了 s。如果它有并且仍然有位置参数,那么它会打印一条消息:

[ -r "$filepath" ] && source "$filepath" # Set all override variables
[ -n "$s" ] && [ "$#" -gt 0 ] && echo "message"

在测试 ([...]) 语句中,请注意 $filepath$s 包含在双引号中。这可以防止任何一个值都为空时出现错误。如果 filepath 的值包含空格,它还可以防止错误。

要获取一个文件,它不仅需要存在,还需要可读。因此,上面的第一个测试检查可读性 (-r) 而不是仅仅存在 (-f)。

更多

检查源文件是否有任何变量设置为空值的未注释行:

grep -qE '^[^#]+=$' file1 && echo "message"

上面的^匹配一行的开头。

正则表达式起作用是因为 [^#] 匹配任何不是井号的字符。由于加号表示一个或多个前面的字符,因此 [^#]+ 表示一个或多个字符的字符串,其中没有一个是井号。在方括号之外,^ 匹配一行的开头。因此,^[^#]+ 匹配从行首开始的任何非散列字符字符串。 ^[^#]+= 如果这些字符后跟等号则匹配。由于 $ 匹配一行的结尾,那么 ^[^#]+=$ 如果该行以一个或多个非散列字符开头,后跟一个等号,则匹配符号,后面什么也没有(行尾)。因此,如果某个变量的值设置为空,它就会匹配。

关于shell - shell 中的方括号(测试条件)内容和高级案例陈述,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21873888/

相关文章:

shell - 从 Fish 脚本检查程序是否存在

linux - linux/unix 中的 spawn、expect 和 send 命令是什么

javascript - 如何阻止 Protractor 在失败时运行进一步的测试用例?

java - charAt 无法在 Java 分数计算器中工作

shell - 删除重复行而不排序

linux - 我如何在 Windows 上运行 Ubuntu 的/bin/bash

testing - Playframework 2.1 测试 POST 请求中的无效 JSON

performance - 对等点 : socket write error/socket exception: connection reset 重置 Jmeter 连接

linux - 如何在 Bash 中的 If 语句中更改变量值?

mysql - MySQL 上的条件语句