As stated by the other answers:

- The problem is the `;` after the `&`.
- Deleting the `;` after the `&` will result in a command
that will run without shell syntax errors. 
However, it is unlikely to function correctly,
because it creates a race condition.

The OP stated that he resolved the race condition by adding a 3 second delay.

Nobody mentioned:

- A 3 second delay might work today. 
Tomorrow, the computer might be more sluggish, and it could fail again. 
Next year, the script might be modified to be more time-consuming,
and it could fail again. 
The probability of failure goes down if you increase the delay
by an order of magnitude, by which I mean 30 seconds. 
Of course this means that the script processes will (probably / presumably)
be running essentially sequentially, and not concurrently (in parallel),
thus defeating the purpose of making the processes asynchronous.
- If running multiple instances of the script is a requirement,
it’s probably best to modify the script to accept the number parameter
on the command line:
 ```
 for ((i=114;i<=255;i++)); do python DoMyScript.py --number="$i" & done
 ```
 and do away with the file.
- If changing the script is not an option, this solution should work:
 ```
 for i in {114..125}; do ( subdir="dir.$i" && mkdir "$subdir" && cd "subdir" && 
 echo "$i" > numbers.txt && python ../DoMyScript.py; cd .. && rm -r "$subdir" ) & done
 ```
 This gives each script process a separate `numbers.txt` file,
by giving it a separate directory to run in. 
The directory is created and deleted, and the script is run, in a subshell.
 - If `DoMyScript.py` accesses any files other than `numbers.txt`
by relative pathnames,
the above command will need to be adjusted to accommodate that.
 - The above was inspired by [glenn jackman’s answer][1]
(although I believe that mine will work and his won’t).
 - If command *`B`* depends on the success of command *`A`*,
then <code><i>A</i> && <i>B</i></code> is better defensive programming
than <code><i>A</i>; <i>B</i></code>. 
But it’s probably not the ideal way to handle this situation. 
If `mkdir dir.114` fails, then the next 111 attempts are likely to fail also,
and you’ll get 112 error messages. 
It would be better to abort the loop if a fatal error occurs.

 The fact that the action is happening in an asynchronous subshell
makes this somewhat tricky.
 ```
 for i in {114..125}; do
 { subdir="dir.$i" && mkdir "$subdir" && echo "$i" > "$subdir"/numbers.txt; } || break;
 ( cd "$subdir" && python ../DoMyScript.py; cd .. && rm -r "$subdir" ) & done
 ```
 will cause the loop to abort if a `mkdir`
or an <code>echo <i>value</i> &gt; <i>file</i></code> command fails.
 - It might be better to work in a directory
that is ‘‘guaranteed’’ to be writable, like `/tmp`. 
However, this increases the risk that your command
will collide (interfere) with some other process.
 - You can mitigate this by adding `$$` to the directory name;
e.g., `dir.$$.$i` or even `dir.$BASHPID`.
 - This would not eliminate the risk that the `mkdir`
or the file creation might fail because the filesystem is full.
 - Note that the above code will keep on going
and remove the temporary directory even if the script fails. 
You might want to do something else in that situation.
 - Oops. 
If, for some reason,
the `mkdir "$subdir"` succeeds but the `cd "$subdir"` fails,
this will go ahead and do `cd .. && rm -r "$subdir"`. 
If there is a directory with a name like `dir.114` in your parent directory
(i.e., parallel to your current directory), it will be removed. 
I believe that you can (at least somewhat) fix this
by changing the last line to
 ```
 ( cd "$subdir" && { python ../DoMyScript.py; cd ..; } && rm -r "$subdir" ) & done
 ```
 or by using absolute paths; e.g., `subdir="$PWD/dir.$i"`.

[1]: https://unix.stackexchange.com/q/91684/80216#91713