Question: How can I pass a `sed` command to `popen` without using a raw string?

When I pass an sed command to `popen` in the list form I get an error: `unterminated address regex` (see first example)

```python
>>> COMMAND = ['sed', '-i', '-e', "\$amystring", '/home/map/myfile']
>>> subprocess.Popen(COMMAND).communicate(input=None)
sed: -e expression #1, char 11: unterminated address regex

```

using the raw string form it works as expected:

```python
>>> COMMAND = r"""sed -i -e "\$amystring" /home/map/myfile"""
>>> subprocess.Popen(COMMAND, shell=True).communicate(input=None)

```

I'm really interested in passing `"\$amystring"` as an element of the list. Please avoid answers like 

```python
>>> COMMAND = r" ".join(['sed', '-i', '-e', "\$amystring", '/home/map/myfile'] 
>>> subprocess.Popen(COMMAND, shell=True).communicate(input=None)

```

Answer: 
The difference between the two forms is that with `shell=True` as an argument, the string gets passed as is to the shell, which then interprets it. This results in (with bash):

```
sed -i -e \$amystring /home/map/myfile

```

being run.

With the list args and the default `shell=False`, python calls the executable directly with the arguments in the list. In this case, the literal string is passed to sed,

```
sed -i -e '\$amystring' /home/map/myfile

```

and `'\$amystring'` is not a valid `sed` expression. In this case, you'd need to call 

```
>>> COMMAND = ['sed', '-i', '-e', "$amystring", '/home/map/myfile']
>>> subprocess.Popen(COMMAND).communicate(input=None)

```

since the string does not need to be escaped for the shell.
There is not such thing as a raw string. There are only raw string *literals*.

A literal -- it is something that you type in the Python source code.

`r'\$amystring'` and `'\\$amystring'` are the same *strings objects* despite being represented using different string *string literals*.

As [@Jonathan Villemaire-Krajden said](https://stackoverflow.com/a/28460565/4279): if there is no `shell=True` then you don't need to escape `$` shell metacharacter. You only need it if you run the command in the shell:

```
$ python -c 'import sys; print(sys.argv)' "\$amystring"
['-c', '$amystring']

```

Note: there is no backslash in the output.

Don't use `.communicate()` unless you redirect standard streams using `PIPE`, you could use `call()`, `check_call()` instead:

```
import subprocess

rc = subprocess.call(['sed', '-i', '-e', '$amystring', '/home/map/myfile'])

```

To emulate the `$amystring` sed command in Python (± newlines):

```
with open('/home/map/myfile', 'a') as file:
    print('mystring', file=file)

```