‘Well it’s only passing mv a list of–’ yeah yeah yeah, I know, and that’s why I’m calling bullshit. It should be massively harder to execute filenames. Even if 1970s decisions make that the eternal hideous default: the lack of any idiot-proof standard workaround is incomprehensible.

StackOverflow’s full of competing one-liners and people pointing out how each one is considered harmful. The least-skeezy options use exec. That sentence should make anyone recoil in horror.

This is not a filename problem. This is a tool problem. If a single printable character is going to silently expand into a list of names, then for god’s sake, having it put each name in quotes should be fucking trivial.

  • NeatNit
    link
    fedilink
    arrow-up
    2
    ·
    4 months ago

    I have two questions:

    1. Is this some recent news that you expect us to have heard of? Your post demands context that is not easily understood (but it’s possible to understand through multiple reads)
    2. What shell are you using?

    I’m using bash (GNU bash, version 5.1.16(1)-release) and don’t observe this behavior:

    $ ls
    'first file.txt'  'second file.txt'
    $ cat 'first file.txt' 
    this is originally named "first file.txt"
    $ cat 'second file.txt' 
    this is originally named "second file.txt"
    $ mv *.txt
    $ ls
    'second file.txt'
    $ cat 'second file.txt' 
    this is originally named "first file.txt"
    

    It’s possible that whatever shell you’re using has a bug, but it’s definitely not universal. It’s also possible that this bug only affects builtins like mv and not non-builtin commands.

    • mindbleach@sh.itjust.worksOP
      link
      fedilink
      arrow-up
      1
      ·
      4 months ago

      I expected people have tried to move files… using the move command.

      I did not expect I’d have to specify that there’s a destination, in an explanation of what *.jpg does, not an explanation of what mv does.

      For clarity:

      GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)

      mv *.jpg /mnt/Example/Pictures

      Where it will then die with an error like mv: invalid option -- '1' depending on the contents of the current directory.

      Every search about this has led back to this StackOverflow page sooner or later. All answers address wildcard expansion.

      • NeatNit
        link
        fedilink
        arrow-up
        1
        ·
        edit-2
        4 months ago

        Can you run printf %s\\n *.jpg in that same directory and share the result? I’m really intrigued. If there’s private information in there, I’d be satisfied with just a handful of lines showing the issue with private info replaced with ****s

        Edit: also run alias mv to check whether you have an alias messing things up

        • mindbleach@sh.itjust.worksOP
          link
          fedilink
          arrow-up
          2
          ·
          4 months ago

          bash: alias: mv: not found

          printf %s\\n *.jpg is just a list of filenames on newlines. There’s 75,000 of them. You’ll have to take my word for it.

          Fortunately, GenderNeutralBro’s aside about using ./* instead of * works as expected. Could have been files beginning with _-. None begin with -, exactly.

      • FigMcLargeHuge@sh.itjust.works
        link
        fedilink
        arrow-up
        1
        ·
        4 months ago

        When I run into situations like this, I use the commands that work to write out a script. Eg, in your case the wildcard isn’t working with the mv command, so do something like this:

        ls -1 *.jpg | awk ‘{print “mv "”$1"" /mnt/example/Pictures"}’ > /tmp/movefiles.sh

        Then check the movefiles.sh and make sure it has all of the commands and files properly stated, make that executable, and then run that.

        • mindbleach@sh.itjust.worksOP
          link
          fedilink
          arrow-up
          1
          ·
          4 months ago

          ls | grep | mv would work, except the StackOverflow discussion also highlights how parsing ls can have the same issues.

          I am moving thousands of files at once. If I have to check each one, it’s still wrong.

          The pragmatic answer turns out to be ./* instead of *.

          • FigMcLargeHuge@sh.itjust.works
            link
            fedilink
            arrow-up
            1
            ·
            edit-2
            4 months ago

            I saw that answer and was just offering another option. I am sure xargs might work, but you would need to test as you need a destination passed on each line. Back to my way, I have used it for a lot more than just the move command. I think I used it to do a chmod once where I wanted to check and make sure before I committed to actually running the command(s). You could also use find and the -exec option, which I think was also mentioned here.

            Edit: also, you wouldn’t need to check each one, just the first few and last few to make sure the syntax is correct. Maybe do a wc -l to make sure it’s got the right number of entries and then let it run.