[ILUG] bash script Q
Brian Foster
blf at utvinternet.ie
Fri Apr 5 23:10:00 IST 2002
1) Date: Fri, 5 Apr 2002 20:33:28 +0100
1) From: John Tobin <tobinjt at netsoc.tcd.ie>
1)
1) This seems to work for me and it's written entirely in bash:
1)
1) #!/bin/bash
1) for file in *; do if [ -f $file ]; then
1) read LINE < $file;
1) case $LINE in
1) \%\!) echo $file: valid ;;
1) *) echo $file: invalid ;;
1) esac
1) fi; done
( I've vertically compressed John's code. )
the above will work with any Bourne-ish shell.
however, five nits --- its behavior ...
... on empty files is problematic;
... on unreadable files is perhaps not what's wanted;
... on bizarre filenames (e.g., a file whose name contain
spaces) is probably undesirable;
... on binary files is problematic; and
... on other sorts of bizarre filenames (e.g., one whose
name contains sequences like `\n', i.e., a backslash
followed by the letter `n'), may produce odd output.
the 4th (binary files) cannot(?) be fixed in pure Bourne-ish-ism,
and I will not address the 5th (\n in filenames); but the first
three are easy --- replace `for'-loop guts with something like:
answer=invalid
[ -f "$file" -a -r "$file" ] && read line <"$file" && case $line in
%!*) answer=valid ;;
esac
echo "$file: $answer"
however, as others have mentioned, a better answer is to
use file(1). (the perl(1) solution someone posted was rather
neat as well.) if you have GNU `file', you might want to
take a look at the `-i' option, which has the advantage of
outputting predictable text.
2) Date: Fri, 5 Apr 2002 20:03:30 +0100
2) From: Niall O Broin <niall at linux.ie>
2)
2) > On April 5, niall at linux.ie said:
2) > > The line
2) > >
2) > > if [[ "`file -b $file`" == PostScript\ document\ text* ]] ; then
2) > >
2) > > is some bash magic - [[ str1 == str2 ]] does a pattern match [ ... ]
interesting! I hadn't realized there was a difference between
the `==' (nee `=') and `!=' operators of the classical `[ ... ]'
(nee test(1)) and `[[ ... ]]' commands (which I also recall was
first added by ksh(1)) --- thanks!
be that as it may, it is a bad habit to write things like:
[ "$s1" = foo ]
unless the value of $s1 is strictly known to be safe. (for the
purposes of this discussion, there is no difference between "$s1"
and "`cmd ...`".) consider what happens if $s1 has the value:
!
i.e., the single character `!'. then the test becomes:
[ ! = foo ]
which, classically, is a syntax error. having said that,
bash's `[ ... ]' has a complex hierarchy of rules which,
in this case, Do What Is Meant. the all-Bourne-ish fix:
[ "X$s1" = Xfoo ]
is so trivial, I see no point to relying on bash to DWIM a
(IMHO) bad habit. note, b.t.w., if you do want to rely
on using bash, then you might as well use the more readable
$(...) syntax rather than `...`:
[ "$(file -b "$file")" == ... ]
that syntax --- complete with the ability to nest quotes as
shown --- also first(?) appeared in ksh(1), and is (IMHO)
one of ksh's best features/fixes/changes/improvements over
Bourne's original shell.
cheers!
-blf-
--
Innovative, very experienced, Unix and | Brian Foster Dublin, Ireland
Chorus (embedded RTOS) kernel internals | e-mail: blf at utvinternet.ie
expert looking for a new position ... | mobile: (+353 or 0)86 854 9268
For a resume, contact me, or see my website http://www.blf.utvinternet.ie
More information about the ILUG
mailing list