Bash (or any other Bourne family shell) just doesn't work this way. This doesn't work! Especially if those lines are filenames. Filenames can also contain newlines.Īnother variation on this theme is abusing word splitting and a for loop to (incorrectly) read lines of a file. Nor can you simply change IFS to a newline. Instead of iterating over each file name, the loop will only execute once, assigning to f a string with all the filenames rammed together. This causes the entire output of ls to be treated as a single word. You can't simply double-quote the substitution either: In the ls examples, if the first filename starts with a hyphen, it may lead to pitfall #3. That may seem desirable since ls adds a newline, but if the last filename in the list ends with a newline, `…` or $() will remove that one also. The CommandSubstitution strips all trailing newline characters from its output. It's an external command whose output is intended specifically to be read by a human, not parsed by a script. Depending on which platform you're on, which arguments you used (or didn't use), and whether its standard output is pointing to a terminal or not, ls may randomly decide to replace certain characters in a filename with "?", or simply not print them at all. Pathnames may contain any character except NUL. If the command substitution returns multiple filenames, there is no way to tell where the first one ends and the second one begins. If ls produces any output containing a * character, the word containing it will become recognized as a pattern and substituted with a list of all filenames that match it. If a filename contains glob characters, it undergoes filename expansion (" globbing"). Assuming we have a file named 01 - Don't Eat the Yellow Snow.mp3 in the current directory, the for loop will iterate over each word in the resulting file name: 01, -, Don't, Eat, etc. If a filename contains whitespace (or any character in the current value of $IFS), it undergoes WordSplitting. You must use an entirely different approach. This entire approach is fatally flawed, and there is no trick that can make it work. Yes, it would be great if you could just treat the output of ls or find as a list of filenames and iterate over it. One of the most common mistakes BASH programmers make is to write a loop like this: grep foo bar | while read -r do ((count++)) done.
0 Comments
Leave a Reply. |
Details
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |