使用 bash 中的变量回显 echo 命令
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22997675/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Echoing a echo command with a variable in bash
提问by David
Ok, here is one I am struggling with as we speak. Echoing a echo command with a variable.
好的,这是我们说话时我正在努力解决的问题。使用变量回显 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
My goal is create a script using echo commands then run it later. I just need to figure out how to echo echo/read commands while maintaining my variables.
我的目标是使用 echo 命令创建一个脚本,然后再运行它。我只需要弄清楚如何在维护我的变量的同时回显/读取命令。
edit: the variables need to transfer what's inside of them into the new file.
编辑:变量需要将其中的内容传输到新文件中。
采纳答案by mklement0
The immediate problem is you have is with quoting: by using double-quotes, your variable references are instantlyexpanded, which is probably not what you want.
直接的问题是您有引用:通过使用双引号,您的变量引用会立即扩展,这可能不是您想要的。
Use singlequotesinstead - strings inside single quotes are not expanded or interpreted in any way by the shell.
改用单引号- 单引号内的字符串不会被 shell 以任何方式扩展或解释。
(If you want selectiveexpansion inside a string - i.e., expand some variable references, but not others - do use double quotes, but prefix the $
of references you do notwant expanded with \
; e.g., \$var
).
(如果你想选择一个字符串中的扩展-即扩大一些变量引用,而不是其他人-做使用双引号,但前缀$
你引用的不希望与扩大\
;例如,\$var
)。
However, you're better off using a single here-doc[ument], which allows you to create multi-line stdin
input on the spot, bracketed by two instances of a self-chosen delimiter, the opening one prefixed by <<
, and the closing one on a line by itself - starting at the very first column; search for Here Documents
in man bash
or at http://www.gnu.org/software/bash/manual/html_node/Redirections.html.
但是,您最好使用单个here-doc[ument],它允许您在现场创建多行stdin
输入,由两个自行选择的分隔符实例括起来,开头的以 为前缀<<
,结束符一个单独的一行 - 从第一列开始;搜索Here Documents
在man bash
或http://www.gnu.org/software/bash/manual/html_node/Redirections.html。
If you quotethe here-doc delimiter(EOF
in the code below), variable references are also notexpanded. As @chepner points out, you're free to choose the methodof quoting in this case: enclose the delimiter in single quotes ordouble quotes, oreven simply arbitrarily escape one character in the delimiter with \
:
如果引用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
As @BruceK notes, you can prefix your here-doc delimiter with -
(applied to this example: <<-"EOF"
) in order to have leading tabsstripped, allowing for indentation that makes the actual content of the here-doc easier to discern.
Note, however, that this only works with actual tabcharacters, not leading spaces.
正如@BruceK 所指出的,您可以在 here-doc 分隔符前加上-
(应用于此示例: <<-"EOF"
) 以去除前导制表符,允许缩进使 here-doc 的实际内容更容易辨别。但是请注意,这仅适用于实际的制表符,不适用于前导空格。
Employing this technique combined with the afterthoughts regarding the script's content below, we get (again, note that actual tabchars. must be used to lead each here-doc content line for them to get stripped):
将这种技术与关于下面脚本内容的事后想法相结合,我们得到(再次注意,必须使用实际的制表符来引导每个 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
Finally, note that in bash
even normal single- or double-quoted strings can span multiple lines, but you won't get the benefits of tab-stripping or line-block scoping, as everythinginside the quotes becomes part of the string.
最后,请注意,bash
即使是普通的单引号或双引号字符串也可以跨越多行,但您不会获得制表符剥离或行块范围的好处,因为引号内的所有内容都将成为字符串的一部分。
Thus, note how in the following #!/bin/bash
has to follow the opening '
immediatelyin order to become the first line of output:
因此,请注意以下内容如何#!/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"
Afterthoughts regarding the contents of your script:
关于脚本内容的事后思考:
- The syntax
$(...)
is preferred over`...`
for command substitution nowadays. - You should double-quote
${ser}
in thegrep
command, as the command will likely break if the value contains embedded spaces (alternatively, make sure that the valued read contains no spaces or other shell metacharacters). - Use
[[ -n $servicetest ]]
to test whether$servicetest
is empty (or perform the command substitution directly inside the conditional) -[[ ... ]]
- the preferred form inbash
- protects you from breaking the conditional if the$servicetest
happens to have embedded spaces; there's NEVER a need to suppress stdout output inside a conditional (whether[ ... ]
or[[ ... ]]
, as no stdout output is passed through; thus, the> /dev/null
is redundant (that said, with a command substitution inside a conditional, stderroutput IS passed through).
- 现在,该语法
$(...)
优于`...`
命令替换。 - 您应该
${ser}
在grep
命令中用双引号引起来,因为如果值包含嵌入的空格,该命令可能会中断(或者,确保读取的值不包含空格或其他 shell 元字符)。 - 使用
[[ -n $servicetest ]]
以测试是否$servicetest
是空的(或直接执行条件内的命令替换) -[[ ... ]]
-在优选形式bash
-保护你从断裂条件,如果$servicetest
恰好有嵌入空格; 从来没有必要在条件中抑制 stdout 输出(无论是[ ... ]
还是[[ ... ]]
,因为没有传递 stdout 输出;因此,这> /dev/null
是多余的(也就是说,在条件中使用命令替换,传递了stderr输出)。
回答by Mihai
You just need to use single quotes:
您只需要使用单引号:
$ echo "$TEST"
test
$ echo '$TEST'
$TEST
Inside single quotes special characters are not special any more, they are just normal characters.
单引号内的特殊字符不再特殊,它们只是普通字符。
回答by GoinOff
echo "echo "we are now going to work with ${ser}" " >> $servfile
Escape all " within quotes with \. Do this with variables like \$servicetest too:
使用 \ 将所有 " 转义到引号内。也可以使用 \$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