好的,这是我在说话时正在努力解决的问题。使用变量回显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命令。
编辑:变量需要将其中的内容传输到新文件中。
答案 0 :(得分:19)
当前的问题是您使用双引号引用:,您的变量引用即时展开,这可能不是您想要的。
使用单个引号而不是 - 单引号内的字符串不会被shell以任何方式展开或解释。
(如果你想在字符串中进行选择性扩展 - 也就是说,扩展一些变量引用,而不是其他引用 - 请使用双引号,但前缀$
引用 >不希望使用\
进行扩展;例如,\$var
)。
但是,您最好使用单个 here-doc [ument] ,这样您就可以创建多行stdin
现场输入,由两个自选分隔符的实例括起来,开头一个以<<
为前缀,而结束一个在一行上 - 从一开始 - 从第一列;在Here Documents
或http://www.gnu.org/software/bash/manual/html_node/Redirections.html中搜索man bash
。
如果引用 here-doc 分隔符(下面的代码中为EOF
),变量引用也不扩展。正如@chepner指出的那样,在这种情况下你可以自由选择引用的方法:用单引号或双引号,或将分隔符括起来em>甚至只是随意使用\
:
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