-2

So I'm doing this exactly the way the tutorial tells me to, and something still doesn't work...

1 #!/bin/bash
2 users=$(ls *.usr)
3 date=$(date +%F)
4 for usr in $users
5 do
6 mv ${usr} ${date}-${users}
7 done

These are the contents of that directory:

1.sh   fila2  fila6  file3  log1         marty1.usr  marty5.usr  marty9.usr  user3
2.sh   fila3  file0  file4  marty0.usr   marty2.usr  marty6.usr  user0       user4
fila0  fila4  file1  file5  marty10.usr  marty3.usr  marty7.usr  user1       user5
fila1  fila5  file2  file6  marty11.usr  marty4.usr  marty8.usr  user2       user6

Now apparently, my script should rename all of the files that end in .usr to have the date in front of their name, but instead, I get this error:

mv: target ‘marty9.usr’ is not a directory
mv: target ‘marty9.usr’ is not a directory
mv: target ‘marty9.usr’ is not a directory
mv: target ‘marty9.usr’ is not a directory
mv: target ‘marty9.usr’ is not a directory
mv: target ‘marty9.usr’ is not a directory
mv: target ‘marty9.usr’ is not a directory 
mv: target ‘marty9.usr’ is not a directory
mv: target ‘marty9.usr’ is not a directory
mv: target ‘marty9.usr’ is not a directory
mv: target ‘marty9.usr’ is not a directory
mv: target ‘marty9.usr’ is not a directory

Again, I have no clue what I'm doing wrong, considering I didn't even ask it anywhere to make a folder called marty9.usr...

iamAguest
  • 483

2 Answers2

4

This is what your tutorial should be telling you:

#!/bin/bash
date=$(date +%F)
for file in *.usr
do
    echo moving "$file" to "$date-$file"
    mv "$file" "$date-$file"
done

where

  • you're not using ls to iterate over filenames
  • you're iterating over the files matched by the pattern directly
  • you're quoting your variables to protect yourself from effects of word splitting and filename expansion.
glenn jackman
  • 85,964
0

So apparently the thing I got wrong was

   6 mv ${usr} ${date}-${users}

It should have been

   6 mv ${usr} ${date}-${usr}

But I still don't understand why this even works at all. I'm not telling the script what usr is anywhere... How does it know that usr is the filename, when I'm not telling it? The "for usr in $users" doesn't make sense to me....

So would this have worked regardless of what I'd have called usr and $usr? Would it have worked if I'd have called it banana and $banana?

Yes, it works even if I call it banana... Why? What's the purpose for that first term then?

To be honest, this isn't a tutorial about shell scripting, it's a broad tutorial about Linux in general, it just has a bit about shell scripting :)

iamAguest
  • 483
  • The for loop iterates over the individual words of the $users variable, storing each word in turn as the usr variable. – glenn jackman Aug 14 '18 at 15:02
  • Thanks glenn, that's actually a really good way of explaining it :D now I understand! – iamAguest Aug 14 '18 at 15:05
  • The downsize of the ls approach is common: what happens when you have a filename that has a space? "my usr file.usr" -- this causes three separate iterations of the for loop, (i) usr="my" (ii) usr="usr" (iii) usr="file.usr". The community wiki answer is not affected by this. – glenn jackman Aug 14 '18 at 15:07
  • This should be an edit to your question. – dr_ Aug 14 '18 at 15:49