Shell脚本:
#!/bin/sh
# -*-sh-*-
java -classpath Test.jar Test test1.xml > javaOutput 2>&1;
if cat javaOutput | tr '\n' ' ' | grep ".*java.lang.indexoutofboundsexception0.*ArrayList.java:653.*Test.java:142.*" &>/dev/null; then
echo TRUE;
else
echo FALSE;
fi
0,2,468.000000
1,2,305.000000
2,5,2702.000000
3,3,1672.000000
Exception in thread "main" java.lang.indexoutofboundsexception: Index: 1, Size: 1
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.get(ArrayList.java:429)
at Test.processpayments(Test.java:113)
at Test.processFile(Test.java:131)
at Test.main(Test.java:142)
我正在使用以下版本的ubuntu:
distributor ID: Ubuntu
Description: Ubuntu 17.04
Release: 17.04
当我将脚本复制并粘贴到命令提示符中时,它可以正常工作并按预期方式回显FALSE,但是每当我执行脚本时,它都会一直回显TRUE.我什至在Mac OS中运行了该脚本,并且该脚本在MacO中按预期执行.我很困惑.任何帮助或见解将不胜感激.
注意:由于输出内容中没有字符串indexoutofboundsexception0,因此这里的期望是FALSE.
解决方法:
我想到了; bash(在POSIX标准指定的基本集之上添加了很多功能的shell程序)和dash(裸机POSIX shell)之间的语法差异很小.许多操作系统都将bash用作/ bin / sh,但是Debian(和Ubuntu)切换到前划线.
语法上的差异是速记&> bash扩展是将标准输出和标准错误都重定向到同一位置的方法;破折号会将其解析为两个单独的标记,即& (表示在后台运行命令的命令定界符),> (标准输出的重定向).自&标记一个命令的结束和另一个命令的开始,重定向不适用于前面的命令,这是它自己的一个最小命令.本质上,破折号将if和then之间的内容解析为:
cat javaOutput | tr '\n' ' ' | grep ".*java.lang.indexoutofboundsexception0.*ArrayList.java:653.*Test.java:142.*" &
>/dev/null
…如果仅查看该块中最后一个命令的成功/失败,那只是一个重定向…而总是成功.
幸运的是,解决方案很简单:不要使用bash速记,而是使用完整的2>& 1来重定向stdout和stderr:
if cat javaOutput | tr '\n' ' ' | grep ".*java.lang.indexoutofboundsexception0.*ArrayList.java:653.*Test.java:142.*" >/dev/null 2>&1; then