Search code examples
unixrustmv

How can I move the first five files in a directory to a new directory?


I am trying to replicate the bash command mv `ls | head -5` ./subfolder1/ in Rust.

This is meant to move the first five files in a directory and it works fine in the shell. I am using the Command process builder but the following code fails at runtime:

Command::new("mv")
    .current_dir("newdir")
    .args(&["`ls | head -5`", "newdir"])
    .env("PATH", "/bin")
    .spawn()

Output:

mv:  cannot stat cannot stat '`ls | head -5`': No such file or directory

Solution

  • As with pretty much all such structures, Command is a frontend to fork followed by the exec* family, meaning it executes one command, it's not a subshell, and it does not delegate to a shell.

    If you want to chain multiple commands you will have to run them individually and wire them by hand, though there exist libraries to provide a shell-style interface (with the danger and inefficiencies that implies).

    Can't rightly see why you'd bother here though, all of this seems reasonably easy to do with std::fs (and possibly a smattering of std::env) e.g.

    for entry in fs::read_dir(".")?.take(5) {
        let entry = entry?;
        fs::rename(entry.path(), dest.join(entry.file_name()))?;
    }