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

Dav*_*vid 21 variables bash shell 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
Run Code Online (Sandbox Code Playgroud)

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

编辑:变量需要将它们内部的内容传输到新文件中.

mkl*_*nt0 23

当前的问题是您使用引号:通过使用双引号,您的变量引用会立即展开,这可能不是您想要的.

改为使用引号 - shell中不会以任何方式扩展或解释单引号内的字符串.

(如果您希望在字符串中进行选择性扩展 - 即,扩展一些变量引用,而不是其他引用 - 请使用双引号,但前缀$为您希望扩展的引用\;例如,\$var).

但是,你最好使用一个here-doc [ument],它允许你在现场创建多行stdin输入,由两个自选分隔符实例括起来,开头一个前缀<<,然后关闭一个在一条线上 - 从第一列开始; 搜索Here Documentsman bashhttp://www.gnu.org/software/bash/manual/html_node/Redirections.html.

如果引用 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
Run Code Online (Sandbox Code Playgroud)

正如@BruceK所指出的那样,你可以在here-doc分隔符前加上-(应用于这个例子:),<<-"EOF"以便删除前导标签,允许缩进,使here-doc的实际内容更容易辨别.但请注意,这仅适用于实际制表符,而不是前导空格.

使用这种技术结合下面关于脚本内容的事后,我们得到(再次注意,必须使用实际的tab chars.来引导每个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
Run Code Online (Sandbox Code Playgroud)

最后请注意,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"
Run Code Online (Sandbox Code Playgroud)

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

  • 现在,语法$(...)优先`...`于命令替换.
  • 您应该${ser}grep命令中双引号,因为如果值包含嵌入的空格,命令可能会中断(或者,确保值读取不包含空格或其他shell元字符).
  • 使用[[ -n $servicetest ]]以测试是否$servicetest是空的(或直接进行内部的命令替换条件) - [[ ... ]]-在优选的形式bash-保护你从断裂条件,如果$servicetest恰好有嵌入空格; 从未有需要抑制内的条件(是否标准输出输出[ ... ][[ ... ]],因为没有标准输出输出被传递通过;因此,> /dev/null是冗余的(即表示,与一个有条件的,内部的命令替换stderr的输出被传递通过).


Mih*_*hai 14

你只需要使用单引号:

$ echo "$TEST"
test
$ echo '$TEST'
$TEST
Run Code Online (Sandbox Code Playgroud)

单引号里面的特殊字符不再特殊,它们只是普通字符.


Goi*_*Off 8

echo "echo "we are now going to work with ${ser}" " >> $servfile
Run Code Online (Sandbox Code Playgroud)

使用\来转义所有"引号内".使用\ $ 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
Run Code Online (Sandbox Code Playgroud)