2017-12-09 01:33:55 -05:00
|
|
|
.. _tutorial_subproc_strings:
|
|
|
|
|
|
|
|
************************************
|
|
|
|
Tutorial: Subprocess Strings
|
|
|
|
************************************
|
|
|
|
Strings in xonsh follow two simple rules:
|
|
|
|
|
|
|
|
1. Strings in xonsh are always parsed in the same way, and
|
|
|
|
2. Python always wins!
|
|
|
|
|
|
|
|
Together these rules mean that **even strings in subprocess mode are treated
|
|
|
|
like Python strings!** This will (help) preserve your sanity.
|
|
|
|
|
|
|
|
No Escape
|
|
|
|
=========
|
|
|
|
Xonsh strings are exactly like Python strings everywhere. Xonsh uses
|
2017-12-09 16:32:59 -05:00
|
|
|
exactly the same escape characters that Python does; no more and no less.
|
2017-12-09 01:33:55 -05:00
|
|
|
This is different from other shells, which have a different set of escape
|
|
|
|
sequences than Python has. Notably, many sh-langs allow you to escape
|
2018-04-04 12:39:38 -04:00
|
|
|
spaces with ``"\ "`` (backslash-space).
|
2017-12-09 01:33:55 -05:00
|
|
|
|
|
|
|
**bash**
|
|
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
|
|
|
$ echo A\ Single\ Argument
|
|
|
|
A Single Argument
|
|
|
|
|
|
|
|
In the above example, since the spaces are escaped, the ``echo`` command
|
|
|
|
only receves a single argument. Xonsh does not allow this. If you were
|
|
|
|
to try this in xonsh, you'd see:
|
|
|
|
|
|
|
|
**xonsh**
|
|
|
|
|
2018-04-04 12:39:38 -04:00
|
|
|
.. code-block:: xonshcon
|
2017-12-09 01:33:55 -05:00
|
|
|
|
|
|
|
$ echo Actually\ Three\ Arguments
|
|
|
|
Actually\ Three\ Arguments
|
|
|
|
|
|
|
|
In this example, echo recives three arguments:: ``"Actually\\"``, ``"Three\\"``,
|
|
|
|
and ``"Arguments"``. Instead, xonsh requires you to use quotes in order to
|
|
|
|
pass in a single argument:
|
|
|
|
|
|
|
|
**xonsh** or **bash**
|
|
|
|
|
2018-04-04 12:39:38 -04:00
|
|
|
.. code-block:: xonshcon
|
2017-12-09 01:33:55 -05:00
|
|
|
|
|
|
|
$ echo "A Single Argument"
|
|
|
|
A Single Argument
|
|
|
|
|
|
|
|
Using quotes is arguably what should have been done in sh-lang in the
|
|
|
|
first place.
|
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
|
|
When in doubt in subprocess mode, use quotes!
|
|
|
|
|
|
|
|
|
|
|
|
Justification
|
|
|
|
=============
|
|
|
|
The reasons for not having additional escape sequences, as in sh-langs, are:
|
|
|
|
|
|
|
|
1. Escape charaters can get overwhemlingly ugly, fast.
|
|
|
|
2. We have escape characters, they are called quotes :)
|
|
|
|
3. We have literal input in subprocess mode via macros.
|
|
|
|
|
|
|
|
On this last point, if you don't already know about
|
|
|
|
`Subprocess Macros <tutorial_macros.html#subprocess-macros>`_,
|
|
|
|
these allow all input following an ``!`` to be treated as a single argument.
|
|
|
|
For example,
|
|
|
|
|
|
|
|
**xonsh**
|
|
|
|
|
2018-04-04 12:39:38 -04:00
|
|
|
.. code-block:: xonshcon
|
2017-12-09 01:33:55 -05:00
|
|
|
|
|
|
|
$ echo! A Single Argument
|
|
|
|
A Single Argument
|
|
|
|
|
|
|
|
Subprocess macros are the ultimate escape mechanism.
|
|
|
|
|
|
|
|
The Quotes Stay
|
|
|
|
===============
|
|
|
|
In sh-langs, internal quote characters are removed. For instance:
|
|
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
|
|
|
$ echo foo"bar"baz
|
|
|
|
foobarbaz
|
|
|
|
|
|
|
|
$ echo --key="value"
|
|
|
|
--key=value
|
|
|
|
|
2017-12-09 16:32:59 -05:00
|
|
|
Xonsh considers this behavior insane. Instead, xonsh treats these
|
2017-12-09 01:33:55 -05:00
|
|
|
arguments as if they were surrounded in another, outer level of
|
|
|
|
quotation (``'foo"bar"baz'``). Xonsh will keep the quotation marks
|
2017-12-09 16:23:32 -05:00
|
|
|
when leading and trailing quotes are not matched.
|
2017-12-09 01:33:55 -05:00
|
|
|
|
|
|
|
**xonsh**
|
|
|
|
|
2018-04-04 12:39:38 -04:00
|
|
|
.. code-block:: xonshcon
|
2017-12-09 01:33:55 -05:00
|
|
|
|
|
|
|
$ echo foo"bar"baz
|
|
|
|
foo"bar"baz
|
|
|
|
|
|
|
|
$ echo --key="value"
|
|
|
|
--key="value"
|
|
|
|
|
|
|
|
You can think of these being equivalent to,
|
|
|
|
|
|
|
|
|
|
|
|
**xonsh**
|
|
|
|
|
2018-04-04 12:39:38 -04:00
|
|
|
.. code-block:: xonshcon
|
2017-12-09 01:33:55 -05:00
|
|
|
|
|
|
|
$ echo 'foo"bar"baz'
|
|
|
|
foo"bar"baz
|
|
|
|
|
|
|
|
$ echo '--key="value"'
|
|
|
|
--key="value"
|
|
|
|
|
2017-12-09 16:32:59 -05:00
|
|
|
This is yet another major point of departure for xonsh from traditional
|
2017-12-09 01:33:55 -05:00
|
|
|
shells. However, the xonsh subprocess string handling is
|
|
|
|
consistent and predictable.
|
|
|
|
|
|
|
|
Further Reading
|
|
|
|
===============
|
|
|
|
For deeper details on the great string debate, please feel free to read
|
|
|
|
and comment at:
|
|
|
|
|
|
|
|
* `To Quote or Not Quote <https://github.com/xonsh/xonsh/issues/1432>`_
|
|
|
|
* `Quote removal in subprocess mode does not behave as expected <https://github.com/xonsh/xonsh/issues/621>`_
|