开发者

csh different from bash when expend *NAME* patten to file name list

开发者 https://www.devze.com 2022-12-16 03:46 出处:网络
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 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开发者_JAVA技巧 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).


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.


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


Enclose your arguments in single quotes or escape them:

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

or

 tar cf test.tar \*TEST\* \*TEST2\*


Include the string in single quotes:

tar cf test.tar '*TEST2*'


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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消