15
5
Who deals (interprets) the * in
echo *
Does the echo see the star or the shell take care about it and return a list of filename ..
What about
cp temp temp*
15
5
Who deals (interprets) the * in
echo *
Does the echo see the star or the shell take care about it and return a list of filename ..
What about
cp temp temp*
24
bash (or whatever you use as shell), is the first thing to read any input, and will start interpreting special characters such as ?
and *
. *
gets expanded to whatever matches in the CWD, which means that the asterisk is substituted by said matches.
In most cases, this is fairly straght forward, but can lead to some confusing cases from time to time.
Consider the following. A directory has this contents:
If you then type mv *
something seemingly weird happens: test3
is there, but the rest is gone. While weird at first, it makes sense once you understand what bash actually passes to mv
. Because of the asterisk, bash interprets mv *
as mv test test1 test2 test3
, and when mv gets that list, it'll assume that the last arguement is the destination, which is where all of the files would've been moved.
As for the commands you listed:
echo *
can function as a poor-mans ls
. The shell will expand the asterisk to whatever is in that directory, and as I'm sure you already know, echo
will literally just echo anything bash passed to it as arguements.cp temp temp*
will behave somewhat like the mv
command I described above, unless there's only one directory named temp, in which case source and destination name is the same, i.e. it'll do nothing.8There is nothing "poor" about using *
instead of ls
. For example, for f in *; do
is more reliable than for f in $(ls)
if a filename contains whitespace or a glob character. (It will, however, fail if there are no files in the CWD, so you do need to check for that case.) – rici – 2015-04-14T01:59:45.183
1@rici That's what shopt nullglob
is for. – a CVn – 2015-04-14T09:33:28.250
@MichaelKjörling It can, and it certainly has saved me at least once. – Jarmund – 2015-04-14T09:43:27.593
@MichaelKjörling: Yes, that's one possibility. But setting that shopt globally often has unfortunate consequences, too. And you may well want to throw an error: it's actually often the case that an error message of the form cannot open "the_directory/*": No such file or directory
is completely appropriate... – rici – 2015-04-14T17:17:01.110
2Chiming in with: files prepended with "-" in arbitrary folders that trigger undesirable switches. Removing them is not much fun until you realize that rm ./-stupidfile works. – ǝɲǝɲbρɯͽ – 2015-04-14T17:49:22.753
1@ǝɲǝɲbρɯͽ I noticed when I once needed to delete the contents of a directory containing files with the filename representing positions in a coordinate system, from -1024x-1024 to 1024x1024. That's when I first learned about escaping. – Jarmund – 2015-04-14T17:53:23.763
@Jarmund I think I need to brush up on mine; "mv" doesn't give the same hints "rm" does, so I iterated through tab completion, ---sf = unrecognized option (same without escaping), \- no such file. Quoting didn't work, I tried some other things and finally rm hinted. I appreciated this because damned if I was going to cheat with the gui (which is where it came from). – ǝɲǝɲbρɯͽ – 2015-04-14T18:04:32.700
5
As already stated, the shell expands *
so echo
receive as arguments whatever the shell find in the current directory. However, note that if the expansion leads to nothing, i.e. in that case if the directory contains no non-hidden files, the *
is left unchanged and passed as is to the command called (unless non standard options are used with some shells like bash
.) echo *
isn't then going to behave like a poor man's ls
as the former will print nothing while the latter will print *
.
Similarly, cp /tmp/temp temp*
will create a file named temp*
in the current directory if there not yet at least one file which name starts with temp
.
Finally, if you want the *
to be passed unchanged whatever the case, you can protect it from expansion using either single quotes '*'
, double quotes "*"
or backslash \*
.
4
In Bash, the shell deals with it. You see that if you even try *
without echo
Note- based on some comments, I would suggest when running * ENTER, to create a directory and use the touch command to make some files, and make sure none of them , or at least make sure the first one alphabetically, is not the name of any script or command in the path.
$ *
bash: a: command not found
$ echo *
a a.aa a.ab a.b a.htm a.tx
So ls *
is a bit of a cliche
In Windows, *
is handled by the command, so dir *.*
is not a cliche.
Note- Seeing some comments, I would add, there is a risk running * then ENTER. If you have a file called rm that is first in the directory listing, then it's dangerous because anything after it would get deleted. Also, and this is less unlikely, if the first file in the directory listing is the name of a script in the path, then it will run that.
4Note there could be a file named rm
, of course. – Volker Siegel – 2015-04-14T12:53:27.607
1...and another one called -rf – ǝɲǝɲbρɯͽ – 2015-04-14T17:52:33.610
1@ǝɲǝɲbρɯͽ can you have a file whose filename is -rf
? I tried touch -rf
and touch \-rf
but it isn't creating it. – barlop – 2015-04-15T02:12:38.103
@barlop I commented above; the gui (like gedit) handles them fine, but since the shell (at least bash) passes this through it requires ./ in front. Should you ever accidentally create such a file, rm tries to hint, but if doesn't: I hope this only ever ends up in a temp folder with disposable children. – ǝɲǝɲbρɯͽ – 2015-04-15T04:13:31.383
@ǝɲǝɲbρɯͽ I don't understand what you mean at all, i'm asking how can you create a file that is named -rf
? (I understand the danger of a file called rm and a file called -rf, and the problem of typing * and pushing enter in an important folder, I don't plan to do that) – barlop – 2015-04-15T10:19:28.503
@barlop In a comment on Jarmund's answer: rm ./-stupidfile (which means the - is a nuisance). Here, touch ./-rf . Assuming you're using Gnome on Linux, gedit saves a file called -anyfile without issue but rm -anyfile will fail, and might warn you "perhaps you wanted rm ./-anyfile?" instead, which I think instructs the shell to seek a file in the current location (.), rather than considering it a switch to place on the parameter stream. This warning may depend on the shell. Since we're meta the question but not your answer, I don't mind following up in chat. – ǝɲǝɲbρɯͽ – 2015-04-15T14:28:33.520
@ǝɲǝɲbρɯͽ it is meant to spawn a chat link if comments get long. And will give option to import them in. Yes I see touch ./-rf works, though since * would expand "alphabetical" order, -rf before rm, it couldn't ever run rm -rf. – barlop – 2015-04-15T14:41:10.020
-1
The shell performs several expansions before the arguments are handed to the command.
See also https://www.gnu.org/software/bash/manual/bashref.html#Simple-Command-Expansion
Not bash-specific, see http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_01
Technically what you are writing is correct, but without the links, this answer doesn't really do anything to answer the question. Consider incorporating the relevant details. – a CVn – 2015-04-14T09:34:34.710
@MichaelKjörling I agree with the thing about the links, but the OP simply asked whether the shell or the command itself handled the arguments. Glenn's answer simply states that the shell handles them, so it's an acceptable answer to the question. – slhck – 2015-04-14T15:28:44.547
@slhck Which is why I didn't flag as NAA: there's something left that addresses the question after stripping the links. That doesn't mean this is a in my opinion good answer. (I now see that my initial comment could be construed otherwise; for that, I apologize, but I still think it has enough value to leave it where it is.) – a CVn – 2015-04-14T15:46:16.047
@MichaelKjörling Agreed. I just left the comment for those who did (and will) flag it as NAA. – slhck – 2015-04-14T15:47:45.037
14It varies. Unix shells or Windows shells? – user1686 – 2015-04-14T00:19:17.037
@grawity Unix shells. Sorry I did not mention that. – faressoft – 2015-04-14T21:19:23.207
For Unix, the answers below are correct. (On Windows, it's done by individual programs – though usually automatically by the runtime library before main().) – user1686 – 2015-04-14T21:39:22.413