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@lists.fedoraproject.org
To unsubscribe send an email to users-le...@lists.fedoraproject.org

Reply via email to