使用bash中的变量回显echo命令

时间:2014-04-10 19:49:29

标签: bash shell variables echo

好的,这是我在说话时正在努力解决的问题。使用变量回显echo命令。

echo "creating new script file."
echo "#!/bin/bash" > $servsfile
echo "read -p "Please enter a service: " ser " >> $servfile
echo "servicetest=`getsebool -a | grep ${ser}` " >> $servfile
echo "if [ $servicetest > /dev/null ];then " >> $servfile
echo "echo "we are now going to work with ${ser}" " >> $servfile
echo "else" >> $servfile
echo "exit 1" >> $servfile
echo "fi" >> $servfile

我的目标是使用echo命令创建一个脚本,然后再运行它。我只需要弄清楚如何在维护变量的同时回显echo / read命令。

编辑:变量需要将其中的内容传输到新文件中。

3 个答案:

答案 0 :(得分:19)

当前的问题是您使用双引号引用:,您的变量引用即时展开,这可能不是您想要的。

使用单个引号而不是 - 单引号内的字符串不会被shell以任何方式展开或解释。

(如果你想在字符串中进行选择性扩展 - 也就是说,扩展一些变量引用,而不是其他引用 - 请使用双引号,但前缀$引用 >不希望使用\进行扩展;例如,\$var)。

但是,您最好使用单个 here-doc [ument] ,这样您就可以创建多行stdin现场输入,由两个自选分隔符的实例括起来,开头一个以<<为前缀,而结束一个在一行上 - 从一开始 - 从第一列;在Here Documentshttp://www.gnu.org/software/bash/manual/html_node/Redirections.html中搜索man bash

如果引用 here-doc 分隔符(下面的代码中为EOF),变量引用也扩展。正如@chepner指出的那样,在这种情况下你可以自由选择引用的方法:用单引号双引号,甚至只是随意使用\

在分隔符中任意转义一个字符
echo "creating new script file."

cat <<'EOF'  > "$servfile"
#!/bin/bash
read -p "Please enter a service: " ser
servicetest=`getsebool -a | grep ${ser}` 
if [ $servicetest > /dev/null ]; then 
  echo "we are now going to work with ${ser}"
else
  exit 1
fi
EOF

正如@BruceK所说,您可以在here-doc分隔符前加- (适用于此示例:<<-"EOF"),以便具有前导< strong>标签剥离,允许缩进,使here-doc的实际内容更容易辨别。 但请注意,这仅适用于实际的 tab 字符,而不是前导空格。

使用这种技术结合下面关于脚本内容的事后,我们得到(再次注意,实际的 tab 字符必须用于引导每个here-doc内容行,以便它们被剥离):

cat <<-'EOF' > "$servfile"
    #!/bin/bash
    read -p "Please enter a service name: " ser
    if [[ -n $(getsebool -a | grep "${ser}") ]]; then 
      echo "We are now going to work with ${ser}."
    else
      exit 1
    fi
EOF

最后请注意,在bash偶数正常的单引号或双引号字符串可以跨越多行,但是您无法获得制表符剥离或行阻止的好处范围界定,因为引号内的所有成为字符串的一部分。

因此,请注意以下#!/bin/bash如何必须立即跟随开头' 才能成为第一行输出:

echo '#!/bin/bash
read -p "Please enter a service: " ser
servicetest=$(getsebool -a | grep "${ser}")
if [[ -n $servicetest ]]; then 
  echo "we are now going to work with ${ser}"
else
  exit 1
fi' > "$servfile"

关于脚本内容的后续讨论:

  • 如今,语法$(...)优先于`...`进行命令替换。
  • 您应该在${ser}命令中引用grep,因为如果值包含嵌入的空格,命令可能会中断(或者,确保值读取不包含空格或其他shell元字符)。
  • 使用[[ -n $servicetest ]]来测试$servicetest是否为空(或直接在条件内执行命令替换) - [[ ... ]] - bash中的首选表单 - 保护您免受如果$servicetest碰巧有嵌入空格,则打破条件;从来没有必要在条件内抑制stdout输出(无论是[ ... ]还是[[ ... ]],因为没有stdout输出通过;因此,> /dev/null是冗余的(用命令说,条件中的替换, stderr 输出通过)。

答案 1 :(得分:11)

您只需要使用单引号:

$ echo "$TEST"
test
$ echo '$TEST'
$TEST

在单引号内,特殊字符不再特殊,它们只是普通字符。

答案 2 :(得分:8)

echo "echo "we are now going to work with ${ser}" " >> $servfile

逃避所有&#34;在引号内\。使用\ $ servicetest等变量执行此操作:

echo "echo \"we are now going to work with \${ser}\" " >> $servfile    
echo "read -p \"Please enter a service: \" ser " >> $servfile
echo "if [ \$servicetest > /dev/null ];then " >> $servfile