I make some testing below:
---------------------------------------------------------------------------------------------
$ ls
aa.txt ab.txt bb.txt
$ ls | grep -v 'aa.txt' | grep -v 'bb.txt'
ab.txt
$ echo $?
0
$ ls | grep -v 'aa.txt' | grep -v 'bb.txt' |grep -v 'ab.txt'
$ echo $?
1
$ ls | grep -E -v '(aa.txt|bb.txt|ab.txt)'
grep: illegal option -- E
Usage: grep -hblcnsviw pattern file . . .
$ ls | /usr/xpg4/bin/grep -E -v '(aa.txt|bb.txt|ab.txt)'
$ echo $?
1
$ ls abc.txt
abc.txt: No such file or directory
$ echo $?
2
--------------------------------------------------------------
From the testing above, we can find that if ls can’t find certain file,the return value will be 2,and display some error message, that is this command failed. If we use ls without parameters and there are no files in the current diretory, ls will return 0, that is this command successfully be executed.
But grep works in another way. According to the pattern grep will filter some lines. if no line get thought, the return value is 1, if some lines get thought, the return value is 0. so the return value of grep is 1 not mean grep fail, but no line get thought.