1

I have this timeout code block:

#!/bin/bash

WB=$1
sleep 2h;
commands...
kill $WB

To run the script with nohup and in the background, I can paste it in a file, and execute:

nohup /opt/myscript.sh $$ &

What I aim to achieve:

Instead of pasting it in a file and execute, I would like to execute it directly from an heredoc:

/dev/fd/10 10<< 'EOF0'
#!/bin/bash

WB=$1
sleep 2h;
commands...
kill $WB
EOF0

I use an heredoc because heredocs are the only way to paste whole code-blocks directly into Bash, and then execute - Very efficient in my case.

My question:

How could I correctly use nohup and & with the above hereodc?

Note that the above heredoc is a special one, it's an external heredoc (EOF0), allowing 1 or more heredocs inside it (EOF1, EOF2...).

  • Why a here-document and not a function? – AlexP Dec 30 '16 at 1:20
  • Because you can paste heredocuments directly in bash as-as and execute; It's not the case with functions, if I'm not wrong... If I am, please feel free to post an answer with a function. – user149572 Dec 30 '16 at 1:22
  • It seems that I just didn't understand what you are trying to do. – AlexP Dec 30 '16 at 1:28
2

From what i understand, you want to copy the whole content of your script, and paste it as a heredoc to execute it. You can do this, but there's a catch: how do you assign a value to the positional parameter $1 that will appear in the heredoc? The trick here is to pass that argument to bash, by putting it after a -- sign (which separates the arguments you pass to bash itself from the arguments you pass to the script). Bash must of course read the commands from the stdin, so the -s flag must be specified.

To see this at work with the code from your example, open a new pseudoterminal and type this (beware: the quote signs near the first EOF0 are mandatory, they prevent the expansion of $1 inside the heredoc itself):

nohup bash -s -- $$ <<'EOF0' &
#!/bin/bash

WB=$1
sleep 2h;
commands...
kill $WB
EOF0

I must tell you however that EOF0 by itself has no special meaning at all. You can use whatever string you want for a heredoc delimiter (e.g. it could have been 'EOF' or 'HEREDOC_DELIMITER'): what matters is that there are single-quotes surrounding it, near the << sign; this prevents any expansion inside the heredoc, which enables you both to use script argument (just like you can use $1 in the code you posted) and to nest other heredocs.

  • Is it true that If I decide not to define a variable inside the code (WB=$1), and hence not to kill the process using that variable (kill $WB), than I could remove the $$ from after the -- in the heredoc declaration? – user149572 Dec 31 '16 at 1:22
  • Mario, I need the heredoc to be an external heredoc, allowing more heredocs inside it. This is what I use for that /dev/fd/10 10<< 'EOF0'. – user149572 Dec 31 '16 at 1:45
  • The command you want to use, /dev/fd/10 10<< 'EOF0', is just a very roundabout way of executing commands in bash, and is functionally equivalent (although way more hacky, you basically copy the heredoc inside the buffer in file descriptor 10 of a new process, and execute it) to bash -s <<'EOF0'. Both your code and the one in my answer allow you to put heredocs inside heredocs. About the varable, you're right: the $$ is just passed as the first argument to the heredoc script, so if you don't need to use $1 inside the heredoc, you don't need the $$ argument. – Mario Vitale Dec 31 '16 at 11:57
1

Using your code:

nohup bash <<EOF &
WB=$1
sleep 2h;
commands...
kill \$WB
EOF

Note that $1 will be expanded when the code is read; to make $WB expand when the code is executed the $ needs to be quoted.

  • 1
    I need this in regards to the herecdoc I've shown in the code example (/dev/fd/10 10<< 'EOF0')... – user149572 Dec 30 '16 at 1:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy