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. – JohnDoea 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? – JohnDoea 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'. – JohnDoea 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')... – JohnDoea 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

Not the answer you're looking for? Browse other questions tagged or ask your own question.