【问题标题】:Using pipe and egrep in bash function [duplicate]在 bash 函数中使用管道和 egrep [重复]
【发布时间】:2019-02-16 09:57:18
【问题描述】:

我创建了一个函数,要求用户猜测目录中有多少文件,并且我正在尝试检查输入是否有效。对于第 18 行,我正在尝试检查输入是否包含单词,如果是,则通知用户它不是有效输入。但是,我收到以下错误:

guessinggame.sh: line 18: conditional binary operator expected
guessinggame.sh: line 18: syntax error near `$response'
guessinggame.sh: line 18: `    elif [[ echo $response | egrep "\w" response.txt ]'

这是我的代码:

function guessinggame {
num_input=true
while $num_input
do
  echo 'Guess how many files are in the current directory. Type in a number and 
        then press Enter:'
  read response
  echo $response > response.txt
  if [[ $response -eq 3 ]]
  then
    echo 'Congratulations! You guessed correctly!'
    num_input=false
  elif [[ $response -gt 3 ]]
  then
    echo '$response is too high! Guess again.'
  elif [[ $response -lt 3 ]]
  then
    echo '$response is too low! Guess again.'
  elif [[ echo $response | egrep "\w" response.txt ]]
  then
    echo '$response is not a number! Please enter a valid input.'
  else
    echo '$response is not a number! Please enter a valid input.'
  fi
num_input=$num_input
done
}
guessinggame

如何解决此错误?我做错了什么?

【问题讨论】:

  • 将其粘贴到shellcheck.net 并修复它告诉您的所有内容。您缺少右引号,[[ ... ]] 中缺少右引号 ],包含变量的单引号字符串...
  • 另外,num_input=$num_input 什么也没做。
  • 使用echo text | grep ...grep ... file,但不能使用echo text | grep ... file。删除[[ ]] 大括号并添加-qelif ... grep -Eq ...
  • 您还在尝试将这些内容放入[[ ]] 中吗? [[ 是扩展的 test 命令。 echogrep 都不是 test 的参数,无论是扩展的还是其他的——所以你可以运行 if echo foo | grep,但不能if [[ echo foo | grep ]]
  • ...也就是说[[是一个命令,它不是if语法的一部分。

标签: bash grep pipe


【解决方案1】:

给你,正则表达式对我有用:

#!/bin/bash
guessinggame() {
  local num_input response
  num_input=1
  while (( num_input )); do 
    echo 'Guess how many files are in the current directory. Type in a number and 
          then press Enter:'
    read -r response
    echo "$response" > response.txt

    if ! [[ "$response" =~ ^[0-9]+$ ]]; then
      echo "$response is not a number! Please enter a valid input."
    elif (( response == 3 )); then
      echo 'Congratulations! You guessed correctly!'
      num_input=0
    elif (( response > 3 )); then
      echo "$response is too high! Guess again."
    elif (( response < 3 )); then
      echo "$response is too low! Guess again."
    else
      echo "$response is not a number! Please enter a valid input."
    fi
    num_input=$num_input
  done
}

guessinggame

【讨论】:

  • 正则表达式可能有效,但此代码中有很多不好的做法。由于 SO 答案是一种教学资源,您会考虑进行更完整的清理吗? (查看shellcheck.net 标识的所有内容,以及wiki.bash-hackers.org/scripting/obsolete 处有关函数声明语法的注释;此外,使用truefalse 作为布尔值是一种危险的做法,因为未初始化的变量很容易导致任意命令执行)。
  • 如果此代码的结构不同,例如 num_input 并不总是初始化为 true,那么如果该变量的先前值包含除 truefalse 之外的命令,然后该命令(无论它是什么)将由while $num_input 命令运行。运行 while [[ $num_input = true ]] 或将布尔值存储为数字 (num_input=1) 并使用 while (( num_input )); do 会更安全。
  • (类似地,while $num_input 模式意味着您依赖另一个函数、read 命令等使用true/false 填充变量的任何点,您需要担心该功能、read 正在使用的内容等是否跨越信任边界)。
  • ...顺便说一句,我会考虑(( response == 3 ))(( response &gt; 3 ))(( response &lt; 3 )) 而不是[[ $response ... ]] 并且需要-eq/-gt/-lt;如果你打算使用 bashisms,不妨选择那些尽可能提高可读性的。 :)
  • 双括号进入 C 风格的算术上下文,而双括号进入受test 命令(又名[)启发的shell 语法扩展。 BashFAQ #31 很好地涵盖了 [[[,而 wiki.bash-hackers.org/syntax/arith_expr 涵盖了 POSIX 标准化的 $(( )) 及其 bash 扩展 (( )) 表亲。
猜你喜欢
  • 2019-02-24
  • 2012-04-13
  • 1970-01-01
  • 1970-01-01
  • 2013-02-01
  • 1970-01-01
  • 2012-07-12
  • 2016-05-13
  • 2015-10-27
相关资源
最近更新 更多