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"
4
  • 1
    I cannot reproduce the problem you're seeing. Jul 3, 2018 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 3, 2018 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 3, 2018 at 13:45
  • Try { sleep 0.2; echo "abc"; } & echo "abc" to have the same effect. You maybe want && instead of & ?
    – pLumo
    Jul 3, 2018 at 14:00

1 Answer 1

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.

Not the answer you're looking for? Browse other questions tagged .