使引号可以在bash脚本中运行命令

时间:2014-11-13 16:13:40

标签: regex bash

以下代码将my_string保存在文件my_filename和 然后检查pattern1pattern2是否在文件中。该 首先是;第二个不是。

#!/bin/bash

my_string="One two three four" 
pattern1="two three"
pattern2="two four"

my_filename="my_temp_file"

safeGrepCommand() {
    typeset command_to_run="$*"
    typeset ret_code

    # echo command_to_run=$command_to_run
    eval $command_to_run
    ret_code=$?
    if [ $ret_code != 0 ]; then
        printf "Pattern %s is not in the file %s.\n" "${my_pattern}" "${my_filename}"
        exit $ret_code
    fi
}

echo $my_string > $my_filename

grep_command1="grep --quiet ${pattern1} ${my_filename}"
safeGrepCommand "$grep_command1"

grep_command2="grep --quiet ${pattern2} ${my_filename}"
safeGrepCommand "$grep_command2"

rm -f $my_filename

我期待看到输出

Pattern two four is not in the file my_temp_file.

相反,我看到了

grep: three: No such file or directory
grep: four: No such file or directory

当你看到你是否取消注释函数内的回显线时,问题是grep看不到引号。

command_to_run=grep --quiet two three my_temp_file
command_to_run=grep --quiet two four my_temp_file

如何让bash将引号传递给grep?或者,我如何指定"两个三"作为[:space]的正则表达式而不用担心引号。

2 个答案:

答案 0 :(得分:1)

这是在shell函数中重新发送参数的一种方法:

doit_or_complain() {
  # The arguments are captured only to show how to do it. In practice,
  # I would just use "${@}" to run the command.
  local -a command=("$@")
  "${command[@]}"
  local rc=$?
  if ((rc)); then
    echo "The command failed" >> /dev/stderr
  fi
  return $rc
}

这适用于任何随机参数:

doit_or_complain grep "a  b" "./my file with spaces in its name"

如果要将复杂的命令传递给shell函数,则应使用数组:

theCommand=(grep "a  b" "./my file with spaces in its name")
#...
doit_or_complain "${theCommand[@]}"

注意:如果命令失败,OP中的函数使用exit $rc。这将退出当前shell ,而不仅仅是函数,如果不是不安全的话,这可能被认为是一种意想不到的。

答案 1 :(得分:0)

将模式变量用双引号括起来

grep_command1="grep --quiet \"${pattern1}\" \"${my_filename}\""
safeGrepCommand "$grep_command1"

grep_command2="grep --quiet \"${pattern2}\" \"${my_filename}\""
safeGrepCommand "$grep_command2"