On 03/13/2018 01:19 PM, Stephen Morris wrote:
It just seems counter intuitive to me to have to issue another command
(even if one knows of its existence) to get a command to function
"properly".
Having read this thread, I think you may still not grasp what the shell
does and what command (du, in this case) does.
So, let's illustrate with the standard interview question: "How do you
remove a file called '-r'?"
Let's say that you're perusing your filesystem, and you find that
someone has created a file called "-r". You want to remove it. How?
You might start by running "rm -r".
When you enter a command into a shell, it copies your input into a
buffer. First, it breaks your input into words. It uses the value of
the IFS variable to determine what characters separate words. In the
above example, it will produce an array like ["rm", "-r"]. It will then
do expansion of shell variables and globs (the details are in the
EXPANSION section of "man bash"), though in this case there are neither
in the command. Finally, it will search the directories in the PATH
variable (and also its aliases, shell functions, and built-ins) for a
command that matches the first word in the list. It will execute that
program with its list as arguments. Argument 0 will be "rm" and
argument 1 will be "-r".
That's what the shell does.
Now the command runs and parses its arguments. "rm" sees "-r" as an
option argument. It doesn't find any non-option arguments (files to
remove), so it tells you that an operand is missing.
That's what the command does.
You haven't removed the "-r" file, so you try again. Many people will
try quoting the filename. They'll run "rm '-r'".
The shell breaks the input into words again. This time, it consumes the
quotes, because they are meaningful to the shell. The word list is
["rm", "-r"], same as the last time. The outcome is the same.
Some people will try using a glob. They'll run "rm ?r" or "rm *r".
The shell breaks the input into words. This time, the list is ["rm,
"?r"]. There are glob characters this time, so the shell expands
those. "?r" matches a filename, so it gets replaced with "-r" and the
word list is now ["rm", "-r"]. The list is the same as the last one,
and the outcome is the same.
So, how does that apply to your situation?
When you run "du /path/*", the shell breaks that into words: ["du",
"/path/*"]. Since there are globs present, the shell replaces those
before it runs the command. It expands into ["du", "/path/a",
"/path/b", ...]. The "*" isn't passed to the command, it's expanded by
the shell.
When you enter "shopt -s dotglob", you're not modifying the behavior of
"du", you're modifying the behavior of the shell. You're changing the
way the shell handles globs, so that files with a dot prefix will be
matched by globs. When dotglob is enabled, the shell expands the same
word set differently. This time it might be ["du", "/path/.config",
"/path/.local", "/path/a", ...]. "du" behaves exactly the same. It
knows nothing of the dotglob option. It only reports the use for the
files and directories that are given to it as arguments. In the
standard configuration, the shell won't give dot-files as arguments when
it expands "*", but it will when you enable dotglob.
(And if you want to remove a file named "-r" you need to use a complete
path ("/path/-r"), or a relative path ("./-r") or tell rm to stop
parsing option arguments by giving it the "--" argument, as in "rm -- -r".)
_______________________________________________
users mailing list -- users@xxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to users-leave@xxxxxxxxxxxxxxxxxxxxxxx