Search code examples
bashdd

dd with multiple output to script


I want to make multiple copies of a file and I am able to do it like this...

dd if=~/learndir/source.txt | tee >(dd of=~/learndir/un.txt) | tee >(dd of=~/learndir/deux.txt) | tee >(dd of=~/learndir/trois.txt) | tee >(dd of=~/learndir/quatre.txt) | dd of=~/learndir/cinque.txt

my problem is that this works in the terminal but not in a script. Here is a script with the same syntax that I try to execute...

#!/bin/sh

dd if=~/learndir/source.txt | tee >(dd of=~/learndir/un.txt) | tee
>(dd of=~/learndir/deux.txt) | tee >(dd of=~/learndir/trois.txt) | tee >(dd of=~/learndir/quatre.txt) | dd of=~/learndir/cinque.txt

and I get the following error...

~$ sh duplicate5.sh
> duplicate5.sh: 2: duplicate5.sh: Syntax error: "(" unexpected

I don't understand why it works at my dollar prompt but not in a script.


Solution

  • Your shell is /bin/bash and /bin/bash behaves differently from /bin/sh. Use #!/bin/bash in the script and it should be OK. Also, the script has a bad line-break in it.

    Incidentally, a single copy of tee can write to multiple files in a single invocation:

    dd if=~/learndir/source.txt |
    tee >(dd of=~/learndir/un.txt) \
        >(dd of=~/learndir/deux.txt) \
        >(dd of=~/learndir/trois.txt) \
        >(dd of=~/learndir/quatre.txt) |
    dd of=~/learndir/cinque.txt
    

    But using dd and process substitution seems superfluous here:

    cat ~/learndir/source.txt |
    tee ~/learndir/un.txt ~/learndir/deux.txt ~/learndir/trois.txt ~/learndir/quatre.txt \
        > ~/learndir/cinque.txt
    

    Or even:

    tee < ~/learndir/source.txt \
        ~/learndir/un.txt ~/learndir/deux.txt ~/learndir/trois.txt ~/learndir/quatre.txt \
        > ~/learndir/cinque.txt
    

    The I/O redirections can appear in an arbitrary order in this script, so this also works:

    tee < ~/learndir/source.txt > ~/learndir/cinque.txt \
        ~/learndir/un.txt ~/learndir/deux.txt ~/learndir/trois.txt ~/learndir/quatre.txt
    

    Or:

    tee ~/learndir/un.txt ~/learndir/deux.txt ~/learndir/trois.txt ~/learndir/quatre.txt \
        < ~/learndir/source.txt > ~/learndir/cinque.txt
    

    Etc.