Page 1 of 1

Bash question [Solved]

Posted: Thu 07 Jun 2012, 22:10
by zigbert
This small example shows how I often make tests in my scripts

Code: Select all

#!/bin/bash
echo true > /tmp/test1
[ "$(</tmp/test2)" = "true" ] && echo true
As you see, the file test2 won't hold 'true', and bash gives the annoying terminal output:

Code: Select all

line 3: /tmp/test2: No such file or directory
Sure it's true there is no file, but I don't won't to see the message.



For variable content it is enough to use qoutes to skip message.

Code: Select all

[ "$TEST" = "true" ] && echo true
For content of files I can use cat and send errors to /dev/null

Code: Select all

[ "`cat /tmp/test2 2> /dev/null`" = "true" ] && echo true
But in the end I would like to use bash.... and can't find the correct syntax.
I know some of you know it :wink:


Thank you
Sigmund

Posted: Thu 07 Jun 2012, 22:34
by sunburnt
Hi zigbert; I assume that you want just this error removed?
" No such file or directory "

I was going to suggest grep, but I understand what you`re looking for.
Lit me see what I can find... Terry

Posted: Thu 07 Jun 2012, 23:15
by Karl Godt

Code: Select all

[ -f /tmp/test1 ] && { [ "$(</tmp/test2)" = "true" ] && echo true; } 
OR

Code: Select all

exec 2>/dev/null;[ "$(</tmp/test2)" = "true" ] && echo true;exec 2>/dev/stderr
would come into mind

Note : exec 2>/dev/null works in script but not in rxvt as in /etc/rc.d/rc.shutdown

Posted: Fri 08 Jun 2012, 03:37
by sunburnt
I tried all sorts of Bashisms, but they all failed to quell the error output.

Here`s the best idea I came up with:

Code: Select all

sh-4.1# [ -e /tmp/test1 ]&& echo $(</tmp/test1)
true
sh-4.1# [ -e /tmp/test2 ]&& echo $(</tmp/test2)
sh-4.1#

Posted: Fri 08 Jun 2012, 06:05
by Bruce B
I think this is what I used to supress terminal output


command &>/dev/null


~

Posted: Fri 08 Jun 2012, 06:18
by amigo
'1> /dev/null' quietens normal output. '2> /dev/null' quietens error output. '&> /dev/null' quietens them both.

Re: Bash question

Posted: Fri 08 Jun 2012, 12:25
by jamesbond
This seems to do the trick

Code: Select all

#!/bin/bash
echo true > /tmp/test1
exec 2> /dev/null
[ "$(</tmp/test2)" = "true" ] && echo true
But note that you will lose all errors after the exec line (ie all errors goes to /dev/null) after that.

Posted: Fri 08 Jun 2012, 12:33
by jamesbond
Surprisingly, in bash at least, in UTF-8 locale at least (that's my test environment), testing for presence for file first before reading it is faster than blindly read the file and suppress the error.

This code:

Code: Select all

#!/bin/bash

func1() {
	2> /dev/null read p < /etc/xxx
}

func2() {
	[ -e /etc/xxx ] && read p < /etc/xxx
}


p=5
echo -n func1
time for a in $(seq 1 10000); do func1; done
echo

echo -n func2
time for a in $(seq 1 10000); do func2; done
echo 
echo p is $p

exec 2> /dev/null
[ "$(</etc/passwd)" ] && echo passwd there
[ "$(</etc/passwdxxx)" ] && echo passwdxxx there
gives this surprising results:

Code: Select all

func1
real	0m0.331s
user	0m0.270s
sys	0m0.057s

func2
real	0m0.155s
user	0m0.137s
sys	0m0.017s

p is 5
passwd there
I have always been under the impression that the "test" commands are slow and to be avoided (use "case" instead), but apparently it is not so slow after all ... benchmark is king isn't it :oops:

Posted: Fri 08 Jun 2012, 19:47
by sunburnt
jamesbond; Yep, it`s surprising what you find, like Bash takes 0ms.

Like tests on copying an SFS file`s contents showed it`s faster than
copying the loose files on the partition. That`s just sooo weird...
Try it some time!

Posted: Sat 09 Jun 2012, 05:04
by zigbert
Thank you for all feedback
I didn't realize that I could chain several tests. This works

Code: Select all

#!/bin/bash
echo true > /tmp/test1
[ -e /tmp/test2 ] && [ "$(</tmp/test2)" = "true" ] && echo true
Sigmund

Posted: Sun 10 Jun 2012, 04:09
by sunburnt
.
Glad to see the community coming together for a good cause...