tags:

views:

106

answers:

6

I am a newbie for shell script.

I noticed that for command like:

tar cf test.tar *TEST* *TEST2*

sh and bash will expand TEST to a list of file names, while csh will not. I want the shell not to expend, how can I do this?

Use ' or " will lead to other problems. If there is files match pattern *TEST*, but no files match *TEST2*, then the tar will fail.

[EDIT]I think this is an expend difference between bash and csh. When no pattern found for *TEST*, csh will expend to "", while bash will expend to 'TEST' (add quote char).

A: 

Include the string in single quotes:

tar cf test.tar '*TEST2*'
JesperE
use '' will lead to other problem for tar (if *TEST2* can not find a match). but without ', csh works well.
arsane
Do you have asterixes in your filenames, or what are you trying to do?
JesperE
A: 

Put * into single quotes, i.e. '*'

Peter Štibraný
+1  A: 

Enclose your arguments in single quotes or escape them:

 tar cf test.tar '*TEST*' '*TEST2*'

or

 tar cf test.tar \*TEST\* \*TEST2\*
Remo.D
A: 

As answered by others, the immediate solution is to put * inside single-quoted string or to escape it with a backslash.

Anyway, using a star character in a filename, though not forbidden, is a very bad idea.

mouviciel
I actually want a patten match. Not a star character in a filename.
arsane
+2  A: 

From man bash:

If the nullglob option is set, and no matches are found, the word is removed.

For example:

betelgeuse:TEST james$ touch TEST1 TEST3
betelgeuse:TEST james$ ls *TEST* *TEST2*
ls: *TEST2*: No such file or directory
TEST1   TEST3
betelgeuse:TEST james$ shopt -s nullglob
betelgeuse:TEST james$ ls *TEST* *TEST2*
TEST1   TEST3

This is approximately equivalent to the csh behaviour:

[betelgeuse:/tmp/TEST] james% ls *TEST* *TEST2*
TEST1   TEST3

The difference is that csh will return an error if all of the filename patterns on a line fail to match anything:

[betelgeuse:/tmp/TEST] james% ls *TEST4* *TEST2*
ls: No match.

while bash will just return an list of tokens to the command, leading to oddities such as this:

betelgeuse:TEST james$ ls *TEST4* *TEST2*
TEST1   TEST3

*TEST4* and *TEST2* both return nothing; so the ls command believes it has been called with no arguments and just gives a listing of the directory. In your example, tar would (rightly) complain that it's being given no files to work on.

James Polley
Cool! is there a standard way both for all posix standard platform for this problem? Thanks.
arsane
POSIX compliance, ey? Now you're getting tricky..
James Polley
I found for sh on solaris, the shopt is not supported...
arsane
As far as I can tell, the default `bash` behaviour (if the pattern matches nothing, leave the pattern unchanged) is the correct POSIX behaviour.
James Polley
+2  A: 

try this

shopt -s nullglob
tar cf test.tar *TEST* 2>/dev/null

newer version of Solaris comes with bash already. So you can try using bash. If your version of Solaris doesn't have bash, I guess you just have to do it the "longer" way.

for file in *TEST*
do 
   tar uf test.tar "$file"
done
ghostdog74