1、a string separated by white space?
If I execute rm -r *.txt
where there is a lot of TXT file,I get an "Argument list too long" error,it seems to tell me that it equasl to rm -r a.txt b.txt...c.txt
after pathname expansion.
2、just a list object used by the specific command?
If I execute tar --exclude *.txt a.tar.gz a
where there are two TXT files ("a.txt" and "b.txt") ,the result is not the same as executing tar --exclude a.txt b.txt a.tar.gz a
.According to that,maybe we can get the conclusion that just a list object is returned,not a string separated by white space.
I have a dir named a,the structure is like:
a
├── a.txt
├── b.txt
└── cc
If I execute tar --exclude *.txt -czvf a.tar.gz a
,I get result as:
a/
a/cc
"a.tar.gz" is generated successfully without *.txt file.
If I execute tar --exclude a.txt b.txt -czvf b.tar.gz a
,I get result as:
tar: b.txt:cat not stat: no such file or directory
a/
a/cc
a/b.txt
"b.tar.gz" is generated without a.txt and with cc and b.txt
@Jan Hudec
Neither. It returns a list of strings.
Word splitting is performed before filename generation, so at that point, shell already works with a list of strings that will form the command. The generated filenames are inserted, as a separate entry each, into that list.
If I execute rm -r *.txt where there is a lot of TXT file,I get an "Argument list too long" error,it seems to tell me that it equasl to rm -r a.txt b.txt...c.txt after pathname expansion.
So, yes, it is. And if some of the files has space in its name, it will be passed correctly (which it wouldn't if the pattern returned a space-separated string). However:
If I execute
tar --exclude *.txt a.tar.gz a
where there are two TXT files ("a.txt" and "b.txt") ,the result is not the same as executingtar --exclude a.txt b.txt a.tar.gz a
.
You forgot to mention the files are in the a
directory. Therefore the *.txt
will not expand to a.txt
, b.txt
, because there are no such files—there are only a/a.txt
and a/b.txt
. And here comes a quick of bash (zsh can be configured either way): a pattern that does not match anything is left as is. So
tar --exclude *.txt a.tar.gz a
expands to just tar
, --exclude
, *.txt
, a.tar.gz
and a
. And tar
does it's own wildcard processing for the parameter to --exclude
option.
However, if there were also c.txt
and d.txt
in the current directory, it would expand to tar
, --exclude
, c.txt
, d.txt
, a.tar.gz
and a
and break down. To prevent that, quote the pattern:
tar --exclude '*.txt' a.tar.gz a