0

I'm learning bash so this is a simple question probably. I'd like to understand what happens in this case, there's no real use for this script. Let DTEST be a directory that contains some random files.

for filename in " `ls DTEST/*` " ; do
        touch "$filename".txt
done

So the command substitution happens and the ls output should be file1 file2 file3. Then because the command substitution is double quoted the first line of the for loop should be for filename in "file1 file2 file3". I think it should create only one file named file1 file2 file3.txt.

But I've seen it wants to create a file named something like file1'$'\n''file2'$'\n''file3.txt.

I don't understand where the '$'\n'' come from. I read in bash manual that with double quotes \ followed by special characters like n for newline retains its special meaning, but why \n are generated?

  • 7
    Replace `" \`ls DTEST/*\` "` with `DTEST/*`. Please note: [Why *not* parse `ls`?](http://unix.stackexchange.com/questions/128985/why-not-parse-ls) – Cyrus Oct 15 '21 at 08:43
  • I know it can be solved with DTEST/*. I wanted to understand why this happens. Thanks for the link. So the ls output list is separated with newlines even though echo ls DTEST (with command substitution) shows names separeted by spaces. –  Oct 15 '21 at 08:55
  • 1
    @Giustinian0 Without double-quotes around the command substitution, all whitespace (spaces, tabs, *and newlines*) gets converted into word breaks; `echo` then replaces the word brakes with spaces. See [this question](https://stackoverflow.com/questions/29378566/i-just-assigned-a-variable-but-echo-variable-shows-something-else) (it's about a variable rather than a command substitution, but the same thing happens in either case). You should almost always double-quote variable references and command substitutions to avoid this sort of confusion. – Gordon Davisson Oct 15 '21 at 09:25
  • 2
    `" ls DTEST/* "` expands as one single word (because of the double-quotes) with newlines in it (because this is how `ls` works, it outputs several lines; and this is one of the many reasons why parsing `ls` is almost always a bad idea). So your loop is executed only once with `"$filename"` set to this multiline-word. Depending on how you examine the result it can be presented on several lines or, equivalently, on a single line with the `$'\n'` special string for each newline character. – Renaud Pacalet Oct 15 '21 at 12:24

1 Answers1

0

ls DTEST/* outputs each file on a separate line. Also, the output would contain the directory name (i.e. DEST/file1 etc.).

Of course you would never use ls in this way in a real script. Instead you would just use something like

for filename in DEST/*
do
 ...
done 
user1934428
  • 19,864
  • 7
  • 42
  • 87