Search code examples
bashgnu-screengnu-parallel

How can I create screen using piped command


i'm trying to open a new screen for a command which using pipe. I have tried many options e.g:

screen "cat ~/input | parallel --colsep '\t' -j 100 -m sh ~/runner.sh {}"

Maybe i'm missing something with file descriptors or something, but searching efforts were in vain. Thanks.


Solution

  • You cannot directly use shell syntax constructs like { code; } or ; or & or | in arguments you pass to screen (or parallel, or xargs, or etc). The shell will try to parse your command before running it, so anything which looks like

    echo | moo |
    

    will be parsed into a pipeline with the commands echo and moo and nothing (which is of course a syntax error). If you want to echo a pair of literal pipe characters, you have to quote them:

    echo '| moo |'
    

    If you want the quoted stuff to be evaluated after the shell parses it, there are a couple of options.

    • Encapsulate the command externally in a script, so that you can say screen myscript and have the actually useful commands in the script file myscript. (Some useful tools even allow you to use shell functions or even aliases here.)
    • Pass the command sh -c 'morecommands' or bash -c 'morecommands' so that the commands are quoted but end up being executed anyway. This is just another form of encapsulation really, but doesn't require a separate external definition like a script file or shell function.

    So in your example, you could put your code in a script like ./metarunner and then just call screen ./metarunner; or quote the command line like

    screen sh -c "parallel --colsep '\t' -j 100 -m sh $HOME/runner.sh {} <$HOME/input"
    

    (I switched ~ to $HOME here so I could use sh instead of bash. If you need nontrivial Bash features or are too lazy to refactor your code into POSIX shell script, obviously use bash -c instead of sh -c. See also Difference between sh and bash for what the differences are exactly.)

    Tangentially, I also got rid of the useless use of cat.