2

Why does this shell script:

$ curl -d "asd" 0.0.0.0/abc & echo "abc";

results in me having to press enter before it enters the shell again. The curl is just a post request to a simple web server which returns abc.

However, this script does not require me to press enter before entering the shell again

$ echo "abc" & echo "abc"
slm
  • 369,824
aceminer
  • 123
  • 1
    I cannot reproduce the problem you're seeing. – Andy Dalton Jul 03 '18 at 13:40
  • 1
    It doesn't require you to press enter. Only if you'd like to have a new prompt. Try giving another command instead of pressing just enter. It has nothing to do with the semicolon, but more to do with the single ampersand. – Kusalananda Jul 03 '18 at 13:44
  • 1
    is it a timing issue where you have a shell prompt but don't see it ahead of the abc echo result? Try entering date when you appear not to have a shell prompt... – Jeff Schaller Jul 03 '18 at 13:45
  • Try { sleep 0.2; echo "abc"; } & echo "abc" to have the same effect. You maybe want && instead of & ? – pLumo Jul 03 '18 at 14:00

1 Answers1

6

& sends the curl command to the background, where it will run whenever it runs, the shell will not wait for it (it does print the job number and PID). Instead the shell goes on to run echo, which, since it's builtin, may well run faster than curl, so the shell finishes with echo and prints the prompt before curl gets to produce any output.

E.g. the output I get with Bash:

bash ~ $ curl -d "asd" 0.0.0.0/abc & echo "abc";
[1] 26757
abc
bash ~ $ curl: (7) Failed to connect to 0.0.0.0 port 80: Connection refused

There's the prompt on the start of the last line.

Hitting Enter here has the shell print another prompt, at which point it also checks if the background job has completed, and prints a note about that:

[1]+  Exit 7                  curl -d "asd" 0.0.0.0/abc
bash ~ $ 

Now, I'm not sure what exactly it is you're doing, but having background jobs that print to the terminal is a bit awkward because of this, so you might want to redirect the output of curl elsewhere, or run it in the foreground. E.g. curl something; echo curl done would run curl first, then echo, and curl something && echo curl done would only run echo if curl doesn't fail.

ilkkachu
  • 138,973