bash Shell 脚本,将命令输出存储在变量中并保留格式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8837129/
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
Shell scripting, store command output in variable and preserve formatting
提问by Madasi
Possible Duplicate:
Capturing multiple line output to a bash variable
可能的重复:将
多行输出捕获到 bash 变量
I have what is probably a basic scripting question, but I haven't been able to find an answer anywhere that I've looked.
我有一个可能是基本脚本问题的问题,但我在任何地方都找不到答案。
I have an awk script that processes a file, and spits out a list of disabled systems. When I call it manually from the command line, I get formatted output back:
我有一个处理文件的 awk 脚本,并输出禁用系统的列表。当我从命令行手动调用它时,我得到格式化的输出:
$awk -f awkscript datafile
The following notifications are currently disabled:
host: bar
host: foo
I am writing a wrapper script to call from my crontab, which will run the awk script, determine if there is any output, and email me if there is. It looks like (simplified):
我正在编写一个包装脚本以从我的 crontab 调用,它将运行 awk 脚本,确定是否有任何输出,如果有,请给我发电子邮件。它看起来像(简化):
BODY=`awk -f awkscript datafile`
if [ -n "$BODY" ]
then
echo $BODY | mailx -s "Disabled notifications" [email protected]
else
echo "Nothing is disabled"
fi
When run this way, and confirmed by adding an echo $BODY
into the script, the output is stripped of the formatting (newlines are mainly what I'm concerned with), so I get output that looks like:
当以这种方式运行时,并通过echo $BODY
在脚本中添加一个来确认,输出会被去除格式(换行符主要是我所关心的),所以我得到的输出看起来像:
The following notitifications are currently disabled: host: bar host: foo
I'm trying to figure out how to preserve the formatting that is present if I run the command manually.
我试图弄清楚如果我手动运行命令,如何保留存在的格式。
Things I've tried so far:
到目前为止我尝试过的事情:
echo -e `cat datafile | awkscript` > /tmp/tmpfile
echo -e /tmp/tmpfile
I tried this because on my system (Solaris 5.10), using echo without the -e ignores standard escape sequences like \n . Didn't work. I checked the tmpfile, and it doesn't have any formatting in it, so the problem is happening when storing the output, not when printing it out.
我尝试这样做是因为在我的系统(Solaris 5.10)上,使用没有 -e 的 echo 会忽略像 \n 这样的标准转义序列。没用。我检查了 tmpfile,它没有任何格式,所以问题是在存储输出时发生的,而不是在打印输出时发生。
BODY="$(awk -f awkscript datafile)"
echo -e "$BODY"
I tried this because everything I could find, including some other questions here on stackoverflow said that the problem was that the shell would replace whitespace codes with spaces if it wasn't quoted. Didn't work.
我尝试了这个,因为我能找到的所有东西,包括这里关于 stackoverflow 的一些其他问题,都说问题是如果没有引用,shell 会用空格替换空格代码。没用。
I've tried using printf instead of echo, using $(command) instead of `command`, and using a tempfile instead of a variable to store the output, but nothing seems to retain the formatting.
我试过使用 printf 而不是 echo,使用 $(command) 而不是 `command`,并使用临时文件而不是变量来存储输出,但似乎没有保留格式。
What am I missing, or is there another way to do this which avoids this problem all together?
我错过了什么,或者有另一种方法可以避免这个问题吗?
回答by Jonathan Leffler
BODY=`awk -f awkscript datafile`
if [ -n "$BODY" ]
then echo "$BODY" | mailx -s "Disabled notifications" [email protected]
else echo "Nothing is disabled"
fi
Note the double quotes in the echo
.
请注意echo
.
You can simplify this version, too:
您也可以简化此版本:
echo -e `cat datafile | awkscript` > /tmp/tmpfile
echo -e /tmp/tmpfile
to just:
只是:
tmpfile=/tmp/tmpfile.$$
awkscript > $tmpfile
if [ -s $tmpfile ]
then mailx -s "Disabled notifications" [email protected] < $tmpfile
else echo "Nothing is disabled"
fi
Backquotes are useful (but better written as $(cmd args)
) but do not have to be used everywhere.
反引号很有用(但最好写成$(cmd args)
),但不必到处使用。
回答by Kevin
Using quotes should work, and does for me:
使用引号应该有效,并且对我有用:
$ cat test.sh
#!/bin/bash -e
BODY=`cat test.in`
if [ -n "$BODY" ]; then
echo "$BODY" | mailx -s "test" username
else
echo "Nothing"
fi
$ cat test.in
The following notifications are currently disabled:
host: bar
host: foo
$ ./test.sh
$
And this sends me a properly formatted email.
这会向我发送一封格式正确的电子邮件。