1

Kia ora,

I have a build script where I do a bunch of file operations and if they succeed, I print stuff to stdout as part of a report generated for the build. However I am getting the error "mv: missing destination file operand after" a lot.

if mv $(ls *.md | grep -v _index.md) markdown; then
    echo "    Put Markdown files back in 'markdown'"
fi

I have been reading that it is usually people have just missed the destination part of the command, but in this case I don't think that I have.

Any advice would be appreciated!

Finn LeSueur
  • 111
  • 2
  • 3
    You should really avoid constructs like $(ls *.md | grep -v _index.md) - in bash, you could more robustly set the nullglob and extglob options i.e. shopt -s nullglob extglob and then use mv -t markdown/ !(_index).md I think – steeldriver Sep 09 '20 at 22:59
  • 1
    ... the error could simply be because ls *.md | grep -v _index.md returns no matches, so that your command becomes mv markdown – steeldriver Sep 09 '20 at 23:42
  • I think that is what is happening, too! Is there a way to avoid the grumbly error? – Finn LeSueur Sep 09 '20 at 23:46

1 Answers1

3

Likely the error is because $(ls *.md | grep -v _index.md) evaluates to an empty string (i.e. there are no .md files that do not match _index.md) so that your command becomes

mv markdown

In general, you should avoid constructions like $(ls *.md | grep -v _index.md) for the reasons discussed here:

Bash has a couple of nice "globbing" features that allow you to avoid such problems:

#!/bin/bash

shopt -s nullglob extglob

mdfiles=( !(_index).md )

if (( ${#mdfiles[@]} > 0 )); then if mv -t markdown/ -- "${mdfiles[@]}"; then echo " Put Markdown files back in 'markdown'" fi else echo " No Markdown files to move" fi

This should work unless the number of .md files is large enough to overflow the shell's ARG_MAX.

See also

Zanna
  • 70,465
steeldriver
  • 136,215
  • 21
  • 243
  • 336