xonsh/docs/tutorial.rst

1417 lines
47 KiB
ReStructuredText
Raw Normal View History

2015-03-08 01:01:59 -06:00
.. _tutorial:
*******************
Tutorial
*******************
2015-03-22 15:48:26 -04:00
xonsh is a shell language and command prompt. Unlike other shells, xonsh is
based on Python, with additional syntax added that makes calling subprocess
commands, manipulating the environment, and dealing with the file system
2015-10-06 18:18:25 -07:00
easy. The xonsh command prompt gives users interactive access to the xonsh
2015-03-22 15:48:26 -04:00
language.
2015-03-08 01:01:59 -06:00
2016-06-04 15:36:21 -04:00
While all Python code is also xonsh, not all Bash code can be used in xonsh.
2015-03-22 15:48:26 -04:00
That would defeat the purpose, and Python is better anyway! Still, xonsh is
2016-06-04 15:36:21 -04:00
Bash-wards compatible in the ways that matter, such as for running commands,
reading in the Bash environment, and utilizing Bash tab completion.
2015-03-08 01:01:59 -06:00
The purpose of this tutorial is to teach you xonsh. There are many excellent
2015-03-22 15:48:26 -04:00
guides out there for learning Python, and this will not join their ranks.
Similarly, you'd probably get the most out of this tutorial if you have already
used a command prompt or interactive interpreter.
2015-03-08 01:01:59 -06:00
Let's dive in!
Starting xonsh
========================
2016-02-10 02:43:04 -05:00
Assuming you have successfully installed xonsh (see http://xon.sh),
2015-03-08 01:01:59 -06:00
you can start up the xonsh interpreter via the ``xonsh`` command. Suppose
you are in a lesser terminal:
.. code-block:: bash
bash $ xonsh
2015-03-08 01:50:48 -06:00
snail@home ~ $
2015-03-08 01:01:59 -06:00
Now we are in a xonsh shell. Our username happens to be ``snail``, our
hostname happens to be ``home``, and we are in our home directory (``~``).
2015-03-22 15:48:26 -04:00
Alternatively, you can setup your terminal emulator (xterm, gnome-terminal,
2015-03-08 20:52:56 -05:00
etc) to run xonsh automatically when it starts up. This is recommended.
2015-03-08 01:01:59 -06:00
Basics
=======================
2015-03-22 15:48:26 -04:00
The xonsh language is based on Python, and the xonsh shell uses Python to
interpret any input it receives. This makes simple things, like arithmetic,
2015-03-08 01:50:48 -06:00
simple:
2015-03-30 20:50:20 -05:00
.. code-block:: xonshcon
2015-03-08 01:50:48 -06:00
>>> 1 + 1
2
2015-03-22 15:48:26 -04:00
.. note:: From here on we'll be using ``>>>`` to prefix (or prompt) any
xonsh input. This follows the Python convention and helps trick
2015-03-08 01:50:48 -06:00
syntax highlighting, though ``$`` is more traditional for shells.
2015-03-22 15:48:26 -04:00
Since this is just Python, we are able import modules, print values,
2015-03-08 01:50:48 -06:00
and use other built-in Python functionality:
2015-03-30 20:50:20 -05:00
.. code-block:: xonshcon
2015-03-08 01:50:48 -06:00
>>> import sys
>>> print(sys.version)
2015-03-22 15:48:26 -04:00
3.4.2 |Continuum Analytics, Inc.| (default, Oct 21 2014, 17:16:37)
2015-03-08 01:50:48 -06:00
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]
We can also create and use literal data types, such as ints, floats, lists,
2015-03-22 15:48:26 -04:00
sets, and dictionaries. Everything that you are used to if you already know
2015-03-08 01:50:48 -06:00
Python is there:
2015-03-30 20:50:20 -05:00
.. code-block:: xonshcon
2015-03-08 01:50:48 -06:00
>>> d = {'xonsh': True}
>>> d.get('bash', False)
False
2015-03-22 15:48:26 -04:00
The xonsh shell also supports multi-line input for more advanced flow control.
2015-03-08 20:52:56 -05:00
The multi-line mode is automatically entered whenever the first line of input
2015-03-22 15:48:26 -04:00
is not syntactically valid on its own. Multi-line mode is then exited when
2015-03-08 01:50:48 -06:00
enter (or return) is pressed when the cursor is in the first column.
2015-03-30 20:50:20 -05:00
.. code-block:: xonshcon
2015-03-08 01:50:48 -06:00
>>> if True:
... print(1)
... else:
... print(2)
...
1
Flow control, of course, includes loops.
2015-03-30 20:50:20 -05:00
.. code-block:: xonshcon
2015-03-08 01:50:48 -06:00
>>> for i, x in enumerate('xonsh'):
... print(i, x)
...
0 x
1 o
2 n
3 s
4 h
2015-03-22 15:48:26 -04:00
We can also define and call functions and classes. I'll mostly spare you the
2015-03-08 01:50:48 -06:00
details, but this *is* pretty cool:
2015-03-30 20:50:20 -05:00
.. code-block:: xonshcon
2015-03-08 01:50:48 -06:00
>>> def f():
... return "xonsh"
...
>>> f()
'xonsh'
2015-03-19 17:39:10 +02:00
For easier indentation, Shift+Tab will enter 4 spaces.
2015-03-22 15:48:26 -04:00
And that about wraps it up for the basics section. It is just like Python.
2015-03-08 15:11:36 -05:00
Environment Variables
=======================
2015-03-22 15:48:26 -04:00
Environment variables are written as ``$`` followed by a name. For example,
``$HOME``, ``$PWD``, and ``$PATH``.
2015-03-08 15:11:36 -05:00
2015-03-30 20:50:20 -05:00
.. code-block:: xonshcon
2015-03-08 15:11:36 -05:00
>>> $HOME
'/home/snail'
2015-03-22 15:48:26 -04:00
You can set (and export) environment variables like you would set any other
2015-03-08 15:11:36 -05:00
variable in Python. The same is true for deleting them too.
2015-03-31 01:10:19 -05:00
.. code-block:: xonshcon
2015-03-08 15:11:36 -05:00
>>> $GOAL = 'Become the Lord of the Files'
>>> print($GOAL)
Become the Lord of the Files
>>> del $GOAL
Very nice.
Environment Lookup with ``${}``
--------------
The ``$NAME`` is great as long as you know the name of the environment
variable you want to look up. But what if you want to construct the name
programmatically, or read it from another variable? Enter the ``${}``
operator.
.. warning:: In Bash, ``$NAME`` and ``${NAME}`` are syntactically equivalent.
In xonsh, they have separate meanings.
We can place any valid Python expression inside of the curly braces in
``${<expr>}``. This result of this expression will then be used to look up a
2016-06-21 04:34:30 +03:00
value in the environment. Here are a couple of examples in action:
.. code-block:: xonshcon
>>> x = 'USER'
>>> ${x}
'snail'
>>> ${'HO' + 'ME'}
'/home/snail'
Not bad, xonsh, not bad.
If you want to check if an environment variable is present in your current
session (say, in your awesome new ``xonsh`` script) you can pass an Ellipsis to
the ``${}`` operator:
.. code-block:: xonshcon
>>> 'HOME' in ${...}
True
The Environment ``${...}``
--------------
All environment variables live in the built-in ``${...}`` (aka ``__xonsh_env__``) mapping.
You can access this mapping directly, but in most situations, you shouldnt need to.
One helpful method on the ``${...}`` is :func:`~xonsh.environ.Env.swap`. It can be used to temporarily set an
environment variable:
.. code-block:: xonshcon
>>> with ${...}.swap(SOMEVAR='foo'):
... echo $SOMEVAR
...
...
foo
>>> echo $SOMEVAR
>>>
Environment Types
-----------------
2015-03-08 15:11:36 -05:00
Like other variables in Python, environment variables have a type. Sometimes
this type is imposed based on the variable name. The current rules are pretty
simple:
2015-08-04 22:24:25 -05:00
* ``\w*PATH``: any variable whose name ends in PATH is a list of strings.
* ``\w*DIRS``: any variable whose name ends in DIRS is a list of strings.
2015-03-08 15:11:36 -05:00
* ``XONSH_HISTORY_SIZE``: this variable is an int.
2015-08-04 22:24:25 -05:00
* ``CASE_SENSITIVE_COMPLETIONS``: this variable is a boolean.
2015-03-08 15:11:36 -05:00
xonsh will automatically convert back and forth to untyped (string-only)
representations of the environment as needed (mostly by subprocess commands).
2015-03-22 15:48:26 -04:00
When in xonsh, you'll always have the typed version. Here are a couple of
2015-03-08 15:11:36 -05:00
PATH examples:
2015-03-31 01:10:19 -05:00
.. code-block:: xonshcon
2015-03-08 15:11:36 -05:00
>>> $PATH
2015-03-22 15:48:26 -04:00
['/home/snail/.local/bin', '/home/snail/sandbox/bin',
'/home/snail/miniconda3/bin', '/usr/local/bin', '/usr/local/sbin',
2015-03-08 15:11:36 -05:00
'/usr/bin', '/usr/sbin', '/bin', '/sbin', '.']
>>> $LD_LIBRARY_PATH
2015-03-08 17:57:12 -05:00
['/home/snail/.local/lib', '']
2015-03-08 15:11:36 -05:00
Also note that *any* Python object can go into the environment. It is sometimes
2015-03-08 20:52:56 -05:00
useful to have more sophisticated types, like functions, in the environment.
2015-03-08 15:11:36 -05:00
There are handful of environment variables that xonsh considers special.
They can be seen on the `Environment Variables page <envvars.html>`_.
2015-03-08 15:11:36 -05:00
2016-01-10 19:56:07 -05:00
.. note:: In subprocess mode, referencing an undefined environment variable
will produce an empty string. In Python mode, however, a
``KeyError`` will be raised if the variable does not exist in the
environment.
2015-03-08 16:58:10 -05:00
Running Commands
==============================
2015-03-22 15:48:26 -04:00
As a shell, xonsh is meant to make running commands easy and fun.
2015-03-08 16:58:10 -05:00
Running subprocess commands should work like any other in any other shell.
2015-03-31 01:10:19 -05:00
.. code-block:: xonshcon
2015-03-08 16:58:10 -05:00
>>> echo "Yoo hoo"
Yoo hoo
>>> cd xonsh
>>> ls
2015-03-09 10:54:59 +01:00
build docs README.rst setup.py xonsh __pycache__
2015-03-08 16:58:10 -05:00
dist license scripts tests xonsh.egg-info
2015-05-16 01:37:06 -04:00
>>> dir scripts
xonsh xonsh.bat
2015-03-08 16:58:10 -05:00
>>> git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: docs/tutorial.rst
no changes added to commit (use "git add" and/or "git commit -a")
>>> exit
This should feel very natural.
Python-mode vs Subprocess-mode
================================
It is sometimes helpful to make the distinction between lines that operate
2015-03-22 15:48:26 -04:00
in pure Python mode and lines that use shell-specific syntax, edit the
2015-03-08 20:52:56 -05:00
execution environment, and run commands. Unfortunately, it is not always
2015-03-08 16:58:10 -05:00
clear from the syntax alone what mode is desired. This ambiguity stems from
most command line utilities looking a lot like Python operators.
2015-03-22 15:48:26 -04:00
Take the case of ``ls -l``. This is valid Python code, though it could
have also been written as ``ls - l`` or ``ls-l``. So how does xonsh know
2015-03-08 16:58:10 -05:00
that ``ls -l`` is meant to be run in subprocess-mode?
2015-03-22 15:48:26 -04:00
For any given line that only contains an expression statement (expr-stmt,
see the Python AST docs for more information), if the left-most name cannot
be found as a current variable name xonsh will try to parse the line as a
subprocess command instead. In the above, if ``ls`` is not a variable,
then subprocess mode will be attempted. If parsing in subprocess mode fails,
2015-03-08 16:58:10 -05:00
then the line is left in Python-mode.
2015-03-22 15:48:26 -04:00
In the following example, we will list the contents of the directory
2015-03-08 16:58:10 -05:00
with ``ls -l``. Then we'll make new variable names ``ls`` and ``l`` and then
2015-03-22 15:48:26 -04:00
subtract them. Finally, we will delete ``ls`` and ``l`` and be able to list
2015-03-08 16:58:10 -05:00
the directories again.
2015-03-31 01:10:19 -05:00
.. code-block:: xonshcon
2015-03-08 16:58:10 -05:00
>>> # this will be in subproc-mode, because ls doesn't exist
>>> ls -l
total 0
-rw-rw-r-- 1 snail snail 0 Mar 8 15:46 xonsh
>>> # set an ls variable to force python-mode
>>> ls = 44
>>> l = 2
>>> ls -l
42
>>> # deleting ls will return us to supbroc-mode
>>> del ls
>>> ls -l
total 0
-rw-rw-r-- 1 snail snail 0 Mar 8 15:46 xonsh
The determination between Python- and subprocess-modes is always done in the
safest possible way. If anything goes wrong, it will favor Python-mode.
The determination between the two modes is done well ahead of any execution.
2015-03-22 15:48:26 -04:00
You do not need to worry about partially executed commands - that is
2015-03-08 16:58:10 -05:00
impossible.
2015-05-16 01:37:06 -04:00
If you absolutely want to run a subprocess command, you can always
force xonsh to do so with the syntax that we will see in the following
sections.
2015-03-08 16:58:10 -05:00
2016-03-12 19:33:01 -05:00
Captured Subprocess with ``$()`` and ``!()``
============================================
2015-03-22 15:48:26 -04:00
The ``$(<expr>)`` operator in xonsh executes a subprocess command and
2016-03-12 19:33:01 -05:00
*captures* some information about that command.
The ``$()`` syntax captures and returns the standard output stream of the
2016-06-04 15:36:21 -04:00
command as a Python string. This is similar to how ``$()`` performs in Bash.
2016-03-12 19:33:01 -05:00
For example,
2015-03-08 16:58:10 -05:00
2015-03-30 22:20:22 -05:00
.. code-block:: xonshcon
2015-03-08 16:58:10 -05:00
>>> $(ls -l)
'total 0\n-rw-rw-r-- 1 snail snail 0 Mar 8 15:46 xonsh\n'
2016-03-12 19:33:01 -05:00
The ``!()`` syntax captured more information about the command, as an instance
of a class called ``CompletedCommand``. This object contains more information
about the result of the given command, including the return code, the process
2016-06-09 12:47:07 +10:00
id, the standard output and standard error streams, and information about how
2016-03-12 19:33:01 -05:00
input and output were redirected. For example:
.. code-block:: xonshcon
>>> !(ls nonexistent_directory)
CompletedCommand(stdin=None, stdout='', stderr='/bin/ls: cannot access nonexistent_directory: No such file or directory\n', pid=1862, returncode=2, args=['ls', 'nonexistent_directory'], alias=['ls', '--color=auto'], stdin_redirect=None, stdout_redirect=None, stderr_redirect=None)
This object will be "truthy" if its return code was 0, and it is equal (via
``==``) to its return code. It also hashes to its return code. This allows
for some interesting new kinds of interactions with subprocess commands, for
example:
.. code-block:: xonshcon
def check_file(file):
2016-03-16 12:30:45 -04:00
if !(test -e @(file)):
if !(test -f @(file)) or !(test -d @(file)):
2016-03-12 19:33:01 -05:00
print("File is a regular file or directory")
else:
print("File is not a regular file or directory")
else:
print("File does not exist")
def wait_until_google_responds():
2016-03-16 12:30:45 -04:00
while not !(ping -c 1 google.com):
2016-03-12 19:33:01 -05:00
sleep 1
2016-06-09 21:32:34 -04:00
If you iterate over the ``CompletedCommand`` object, it will yield lines of its
output. Using this, you can quickly and cleanly process output from commands.
Additionally, these objects expose a method ``itercheck``, which behaves the same
as the built-in iterator but raises ``XonshCalledProcessError`` if the process
had a nonzero return code.
.. code-block:: xonshcon
def get_wireless_interface():
"""Returns devicename of first connected wifi, None otherwise"""
for line in !(nmcli device):
dev, typ, state, conn_name = line.split(None, 3)
if typ == 'wifi' and state == 'connected':
return dev
def grep_path(path, regexp):
"""Recursively greps `path` for perl `regexp`
Returns a dict of 'matches' and 'failures'.
Matches are files that contain the given regexp.
Failures are files that couldn't be scanned.
"""
matches = []
failures = []
try:
2016-06-09 21:32:34 -04:00
for match in !(grep -RPl @(regexp) @(str(path))).itercheck():
matches.append(match)
except XonshCalledProcessError as error:
for line in error.stderr.split('\n'):
if not line.strip():
continue
filename = line.split('grep: ', 1)[1].rsplit(':', 1)[0]
failures.append(filename)
return {'matches': matches, 'failures': failures}
2016-03-12 19:33:01 -05:00
The ``$()`` and ``!()`` operators are expressions themselves. This means that
we can assign the results to a variable or perform any other manipulations we
want.
2015-03-08 16:58:10 -05:00
2015-03-30 22:20:22 -05:00
.. code-block:: xonshcon
2015-03-08 16:58:10 -05:00
>>> x = $(ls -l)
>>> print(x.upper())
TOTAL 0
-RW-RW-R-- 1 SNAIL SNAIL 0 MAR 8 15:46 XONSH
2016-03-12 19:33:01 -05:00
>>> y = !(ls -l)
>>> print(y.returncode)
0
2016-03-16 12:30:45 -04:00
>>> print(y.rtn) # alias to returncode
0
2016-03-12 19:33:01 -05:00
.. warning:: Job control is not implemented for captured subprocesses.
2015-03-08 16:58:10 -05:00
2015-03-22 15:48:26 -04:00
While in subprocess-mode or inside of a captured subprocess, we can always
2016-03-12 19:33:01 -05:00
still query the environment with ``$NAME`` variables or the ``${}`` syntax,
or inject Python values with the ``@()`` operator:
2015-03-08 16:58:10 -05:00
2015-03-31 01:10:19 -05:00
.. code-block:: xonshcon
2015-03-08 16:58:10 -05:00
>>> $(echo $HOME)
'/home/snail\n'
2016-03-12 19:33:01 -05:00
Uncaptured Subprocess with ``$[]`` and ``![]``
2016-03-16 01:51:11 -04:00
===============================================
2016-03-12 19:33:01 -05:00
Uncaptured subprocesses are denoted with the ``$[]`` and ``![]`` operators. They are
2015-03-22 15:48:26 -04:00
the same as ``$()`` captured subprocesses in almost every way. The only
2015-03-08 16:58:10 -05:00
difference is that the subprocess's stdout passes directly through xonsh and
2015-03-22 15:48:26 -04:00
to the screen. The return value of ``$[]`` is always ``None``.
2015-03-08 16:58:10 -05:00
2015-03-08 17:22:23 -05:00
In the following, we can see that the results of ``$[]`` are automatically
2016-02-15 21:11:30 +01:00
printed, and the return value is not a string.
2015-03-08 16:58:10 -05:00
2015-03-31 01:10:19 -05:00
.. code-block:: xonshcon
2015-03-08 16:58:10 -05:00
>>> x = $[ls -l]
total 0
2015-03-08 17:57:12 -05:00
-rw-rw-r-- 1 snail snail 0 Mar 8 15:46 xonsh
2015-03-08 16:58:10 -05:00
>>> x is None
True
Previously when we automatically entered subprocess-mode, uncaptured
2015-03-22 15:48:26 -04:00
subprocesses were used. Thus ``ls -l`` and ``$[ls -l]`` are usually
2015-03-08 16:58:10 -05:00
equivalent.
2016-03-12 19:33:01 -05:00
The ``![]`` operator is similar to the ``!()`` in that it returns an object
containing information about the result of executing the given command.
However, its standard output and standard error streams are directed to the
terminal, and the resulting object is not displayed. For example
.. code-block:: xonshcon
>>> x = ![ls -l] and ![echo "hi"]
total 0
-rw-rw-r-- 1 snail snail 0 Mar 8 15:46 xonsh
hi
2015-03-20 17:30:24 -04:00
Python Evaluation with ``@()``
===============================
2015-03-22 15:48:26 -04:00
The ``@(<expr>)`` operator form works in subprocess mode, and will evaluate
2016-06-11 01:53:11 -04:00
arbitrary Python code. The result is appended to the subprocess command list.
If the result is a string, it is appended to the argument list. If the result
is a list or other non-string sequence, the contents are converted to strings
2016-06-11 20:52:47 -04:00
and appended to the argument list in order. If the result in the first position
is a function, it is treated as an alias (see the section on `Aliases`_ below),
even if it was not explicitly added to the ``aliases`` mapping. Otherwise, the
result is automatically converted to a string. For example,
2015-03-20 17:30:24 -04:00
2015-03-31 01:10:19 -05:00
.. code-block:: xonshcon
2015-03-20 17:30:24 -04:00
>>> x = 'xonsh'
>>> y = 'party'
>>> echo @(x + ' ' + y)
xonsh party
>>> echo @(2+2)
4
2015-03-28 17:55:48 -05:00
>>> echo @([42, 'yo'])
42 yo
2016-06-11 20:52:47 -04:00
>>> echo "hello" | @(lambda a, s=None: s.strip + " world")
hello world
2015-03-20 17:30:24 -04:00
This syntax can be used inside of a captured or uncaptured subprocess, and can
be used to generate any of the tokens in the subprocess command list.
2015-03-30 20:50:20 -05:00
.. code-block:: xonshcon
2015-03-20 17:30:24 -04:00
>>> out = $(echo @(x + ' ' + y))
>>> out
'xonsh party\n'
>>> @("ech" + "o") "hey"
hey
2015-03-22 15:48:26 -04:00
Thus, ``@()`` allows us to create complex commands in Python-mode and then
2015-03-20 17:30:24 -04:00
feed them to a subprocess as needed. For example:
2015-03-31 01:10:19 -05:00
.. code-block:: xonsh
2015-03-20 17:30:24 -04:00
for i in range(20):
$[touch @('file%02d' % i)]
Command Substitution with ``@$()``
==================================
A common use of the ``@()`` and ``$()`` operators is allowing the output of a
command to replace the command itself (command substitution):
``@([i.strip() for i in $(cmd).split()])``. Xonsh offers a
short-hand syntax for this operation: ``@$(cmd)``.
Consider the following example:
.. code-block:: xonshcon
>>> # this returns a string representing stdout
>>> $(which ls)
'ls --color=auto\n'
>>> # this attempts to run the command, but as one argument
>>> # (looks for 'ls --color=auto\n' with spaces and newline)
>>> @($(which ls).strip())
xonsh: subprocess mode: command not found: ls --color=auto
>>> # this actually executes the intended command
>>> @([i.strip() for i in $(which ls).split()])
some_file some_other_file
>>> # this does the same thing, but is much more concise
>>> @$(which ls)
some_file some_other_file
2015-03-08 16:58:10 -05:00
2015-03-08 17:22:23 -05:00
Nesting Subprocesses
=====================================
2015-03-20 17:30:24 -04:00
Though I am begging you not to abuse this, it is possible to nest the
subprocess operators that we have seen so far (``$()``, ``$[]``, ``${}``,
``@()``, ``@$()``). An instance of ``ls -l`` that is on the wrong side of the
border of the absurd is shown below:
2015-03-08 17:22:23 -05:00
2016-05-28 19:13:06 -04:00
.. code-block:: console
2015-03-08 17:22:23 -05:00
>>> $[@$(which @($(echo ls).strip())) @('-' + $(printf 'l'))]
2015-03-08 17:22:23 -05:00
total 0
2015-03-08 17:57:12 -05:00
-rw-rw-r-- 1 snail snail 0 Mar 8 15:46 xonsh
2015-03-08 17:22:23 -05:00
With great power, and so forth...
2015-03-20 17:30:24 -04:00
.. note:: Nesting these subprocess operators inside of ``$()`` and/or ``$[]``
2016-02-15 21:11:30 +01:00
works because the contents of those operators are executed in
2015-03-20 17:30:24 -04:00
subprocess mode. Since ``@()`` and ``${}`` run their contents in
Python mode, it is not possible to nest other subprocess operators
inside of them.
2015-05-20 14:43:20 -04:00
Pipes
====================
2015-03-20 17:30:24 -04:00
2015-03-08 17:22:23 -05:00
In subprocess-mode, xonsh allows you to use the ``|`` character to pipe
together commands as you would in other shells.
2015-03-31 01:10:19 -05:00
.. code-block:: xonshcon
2015-03-08 17:22:23 -05:00
>>> env | uniq | sort | grep PATH
DATAPATH=/usr/share/MCNPX/v260/Data/
DEFAULTS_PATH=/usr/share/gconf/awesome-gnome.default.path
2015-03-08 17:57:12 -05:00
LD_LIBRARY_PATH=/home/snail/.local/lib:
2015-03-08 17:22:23 -05:00
MANDATORY_PATH=/usr/share/gconf/awesome-gnome.mandatory.path
PATH=/home/snail/.local/bin:/home/snail/sandbox/bin:/usr/local/bin
XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0
XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session0
2015-03-22 15:48:26 -04:00
This is only available in subprocess-mode because ``|`` is otherwise a
2015-03-08 17:49:18 -05:00
Python operator.
2015-03-08 20:52:56 -05:00
If you are unsure of what pipes are, there are many great references out there.
2015-03-08 17:22:23 -05:00
You should be able to find information on StackOverflow or Google.
2016-02-10 02:13:07 -05:00
Logical Subprocess And
=======================
2016-02-29 21:18:22 -05:00
Subprocess-mode also allows you to use the ``and`` operator to chain together
subprocess commands. The truth value of a command is evaluated as whether
its return code is zero (i.e. ``proc.returncode == 0``). Like in Python,
if the command evaluates to ``False``, subsequent commands will not be executed.
2016-02-10 02:13:07 -05:00
For example, suppose we want to lists files that may or may not exist:
.. code-block:: xonshcon
>>> touch exists
>>> ls exists and ls doesnt
exists
/bin/ls: cannot access doesnt: No such file or directory
2016-02-29 21:18:22 -05:00
However, if you list the file that doesn't exist first,
2016-02-10 02:13:07 -05:00
you would have only seen the error:
.. code-block:: xonshcon
2016-02-29 21:18:22 -05:00
>>> ls doesnt and ls exists
2016-02-10 02:13:07 -05:00
/bin/ls: cannot access doesnt: No such file or directory
Also, don't worry. Xonsh directly translates the ``&&`` operator into ``and``
for you. It is less Pythonic, of course, but it is your shell!
Logical Subprocess Or
=======================
2016-02-29 21:18:22 -05:00
Much like with ``and``, you can use the ``or`` operator to chain together
subprocess commands. The difference, to be certain, is that
2016-02-10 02:13:07 -05:00
subsequent commands will be executed only if the
if the return code is non-zero (i.e. a failure). Using the file example
from above:
.. code-block:: xonshcon
>>> ls exists or ls doesnt
exists
This doesn't even try to list a non-existent file!
2016-02-29 21:18:22 -05:00
However, if you list the file that doesn't exist first,
2016-02-10 02:13:07 -05:00
you will see the error and then the file that does exist:
.. code-block:: xonshcon
2016-02-29 21:18:22 -05:00
>>> ls doesnt or ls exists
2016-02-10 02:13:07 -05:00
/bin/ls: cannot access doesnt: No such file or directory
exists
Never fear! Xonsh also directly translates the ``||`` operator into ``or``,
too. Your muscle memory is safe now, here with us.
2015-05-20 14:43:20 -04:00
2015-05-19 21:55:11 -04:00
Input/Output Redirection
====================================
2015-03-08 17:22:23 -05:00
2015-05-19 21:55:11 -04:00
xonsh also allows you to redirect ``stdin``, ``stdout``, and/or ``stderr``.
This allows you to control where the output of a command is sent, and where
2015-05-20 14:43:20 -04:00
it receives its input from. xonsh has its own syntax for these operations,
2015-07-25 01:58:56 -06:00
but, for compatibility purposes, xonsh also support Bash-like syntax.
2015-03-08 17:49:18 -05:00
2015-05-20 14:43:20 -04:00
The basic operations are "write to" (``>``), "append to" (``>>``), and "read
from" (``<``). The details of these are perhaps best explained through
examples.
2015-03-22 15:48:26 -04:00
2015-05-20 14:43:20 -04:00
Redirecting ``stdout``
----------------------
2015-03-08 17:49:18 -05:00
2015-05-20 14:43:20 -04:00
All of the following examples will execute ``COMMAND`` and write its regular
output (stdout) to a file called ``output.txt``, creating it if it does not
exist:
2015-03-08 17:49:18 -05:00
2015-03-31 01:10:19 -05:00
.. code-block:: xonshcon
2015-03-08 17:49:18 -05:00
2015-05-19 21:55:11 -04:00
>>> COMMAND > output.txt
>>> COMMAND out> output.txt
>>> COMMAND o> output.txt
2015-07-25 01:58:56 -06:00
>>> COMMAND 1> output.txt # included for Bash compatibility
2015-05-20 14:43:20 -04:00
These can be made to append to ``output.txt`` instead of overwriting its contents
by replacing ``>`` with ``>>`` (note that ``>>`` will still create the file if it
does not exist).
Redirecting ``stderr``
----------------------
All of the following examples will execute ``COMMAND`` and write its error
output (stderr) to a file called ``errors.txt``, creating it if it does not
exist:
.. code-block:: xonshcon
2015-05-19 21:55:11 -04:00
>>> COMMAND err> errors.txt
>>> COMMAND e> errors.txt
2015-07-25 01:58:56 -06:00
>>> COMMAND 2> errors.txt # included for Bash compatibility
2015-05-20 14:43:20 -04:00
As above, replacing ``>`` with ``>>`` will cause the error output to be
appended to ``errors.txt``, rather than replacing its contents.
Combining Streams
----------------------
It is possible to send all of ``COMMAND``'s output (both regular output and
error output) to the same location. All of the following examples accomplish
that task:
.. code-block:: xonshcon
2015-05-19 21:55:11 -04:00
>>> COMMAND all> combined.txt
>>> COMMAND a> combined.txt
2015-07-25 01:58:56 -06:00
>>> COMMAND &> combined.txt # included for Bash compatibility
2015-05-20 14:43:20 -04:00
It is also possible to explicitly merge stderr into stdout so that error
messages are reported to the same location as regular output. You can do this
with the following syntax:
.. code-block:: xonshcon
>>> COMMAND err>out
>>> COMMAND err>o
>>> COMMAND e>out
>>> COMMAND e>o
2015-07-25 01:58:56 -06:00
>>> COMMAND 2>&1 # included for Bash compatibility
2015-05-20 14:43:20 -04:00
This merge can be combined with other redirections, including pipes (see the
section on `Pipes`_ above):
.. code-block:: xonshcon
>>> COMMAND err>out | COMMAND2
2015-05-19 21:55:11 -04:00
>>> COMMAND e>o > combined.txt
2015-05-20 14:43:20 -04:00
It is worth noting that this last example is equivalent to: ``COMMAND a> combined.txt``
Redirecting ``stdin``
---------------------
It is also possible to have a command read its input from a file, rather
than from ``stdin``. The following examples demonstrate two ways to accomplish this:
.. code-block:: xonshcon
2015-05-19 21:55:11 -04:00
>>> COMMAND < input.txt
>>> < input.txt COMMAND
2015-05-20 14:43:20 -04:00
Combining I/O Redirects
------------------------
It is worth noting that all of these redirections can be combined. Below is
one example of a complicated redirect.
.. code-block:: xonshcon
>>> COMMAND1 e>o < input.txt | COMMAND2 > output.txt e>> errors.txt
This line will run ``COMMAND1`` with the contents of ``input.txt`` fed in on
stdin, and will pipe all output (stdout and stderr) to ``COMMAND2``; the
regular output of this command will be redirected to ``output.txt``, and the
error output will be appended to ``errors.txt``.
2015-05-19 21:55:11 -04:00
2015-03-08 17:57:12 -05:00
2015-04-06 17:13:43 -04:00
Background Jobs
===============
Typically, when you start a program running in xonsh, xonsh itself will pause
and wait for that program to terminate. Sometimes, though, you may want to
continue giving commands to xonsh while that program is running. In subprocess
mode, you can start a process "in the background" (i.e., in a way that allows
continued use of the shell) by adding an ampersand (``&``) to the end of your
command. Background jobs are very useful when running programs with graphical
user interfaces.
The following shows an example with ``emacs``.
2015-03-08 20:33:33 -05:00
2015-03-31 01:10:19 -05:00
.. code-block:: xonshcon
2015-03-08 20:33:33 -05:00
>>> emacs &
>>>
2015-04-06 17:13:43 -04:00
Note that the prompt is returned to you after emacs is started.
Job Control
===========
If you start a program in the foreground (with no ampersand), you can suspend
that program's execution and return to the xonsh prompt by pressing Control-Z.
This will give control of the terminal back to xonsh, and will keep the program
paused in the background.
2015-05-16 01:37:06 -04:00
.. note:: Suspending processes via Control-Z is not yet supported when
running on Windows.
2015-04-06 17:13:43 -04:00
To unpause the program and bring it back to the foreground, you can use the
``fg`` command. To unpause the program have it continue in the background
(giving you continued access to the xonsh prompt), you can use the ``bg``
command.
You can get a listing of all currently running jobs with the ``jobs`` command.
Each job has a unique identifier (starting with 1 and counting upward). By
default, the ``fg`` and ``bg`` commands operate on the job that was started
most recently. You can bring older jobs to the foreground or background by
specifying the appropriate ID; for example, ``fg 1`` brings the job with ID 1
to the foreground. Additionally, specify "+" for the most recent job and "-"
for the second most recent job.
2015-03-08 20:33:33 -05:00
2015-03-08 17:57:12 -05:00
String Literals in Subprocess-mode
====================================
2015-03-22 15:48:26 -04:00
Strings can be used to escape special characters in subprocess-mode. The
contents of the string are passed directly to the subprocess command as a
2015-03-08 17:57:12 -05:00
single argument. So whenever you are in doubt, or if there is a xonsh syntax
2015-03-22 15:48:26 -04:00
error because of a filename, just wrap the offending portion in a string.
2015-03-08 17:57:12 -05:00
2015-03-22 15:48:26 -04:00
A common use case for this is files with spaces in their names. This
2015-03-08 17:57:12 -05:00
detestable practice refuses to die. "No problem!" says xonsh, "I have
strings." Let's see it go!
2015-03-31 01:10:19 -05:00
.. code-block:: xonshcon
2015-03-08 17:57:12 -05:00
>>> touch "sp ace"
>>> ls -l
total 0
-rw-rw-r-- 1 snail snail 0 Mar 8 17:50 sp ace
-rw-rw-r-- 1 snail snail 0 Mar 8 15:46 xonsh
By default, the name of an environment variable inside a string will be
replaced by the contents of that variable (in subprocess mode only). For
example:
2015-03-08 17:57:12 -05:00
.. code-block:: xonshcon
>>> print("my home is $HOME")
my home is $HOME
>>> echo "my home is $HOME"
my home is /home/snail
You can avoid this expansion within a particular command by forcing the strings
to be evaluated in Python mode using the ``@()`` syntax:
.. code-block:: xonshcon
>>> echo "my home is $HOME"
my home is /home/snail
>>> echo @("my home is $HOME")
my home is $HOME
You can also disable environment variable expansion completely by setting
``$EXPAND_ENV_VARS`` to ``False``.
2015-03-08 17:57:12 -05:00
2015-03-08 19:06:39 -05:00
Filename Globbing with ``*``
===============================
Filename globbing with the ``*`` character is also allowed in subprocess-mode.
2015-03-08 20:52:56 -05:00
This simply uses Python's glob module under-the-covers. See there for more
2015-03-08 19:06:39 -05:00
details. As an example, start with a lovely bunch of xonshs:
2015-03-31 01:10:19 -05:00
.. code-block:: xonshcon
2015-03-08 19:06:39 -05:00
>>> touch xonsh conch konk quanxh
>>> ls
conch konk quanxh xonsh
>>> ls *h
conch quanxh xonsh
>>> ls *o*
conch konk xonsh
2016-02-15 21:11:30 +01:00
This is not available in Python-mode because multiplication is pretty
2015-03-08 19:06:39 -05:00
important.
2016-06-08 22:47:21 -04:00
Advanced Path Search with Backticks
===================================
xonsh offers additional ways to find path names beyond regular globbing, both
in Python mode and in subprocess mode.
Regular Expression Globbing
---------------------------
2015-03-22 15:48:26 -04:00
If you have ever felt that normal globbing could use some more octane,
2015-03-08 19:06:39 -05:00
then regex globbing is the tool for you! Any string that uses backticks
2015-03-22 15:48:26 -04:00
(`````) instead of quotes (``'``, ``"``) is interpreted as a regular
expression to match filenames against. Like with regular globbing, a
2015-03-08 19:06:39 -05:00
list of successful matches is returned. In Python-mode, this is just a
2015-03-08 20:52:56 -05:00
list of strings. In subprocess-mode, each filename becomes its own argument
to the subprocess command.
2015-03-08 19:06:39 -05:00
Let's see a demonstration with some simple filenames:
2015-03-31 01:10:19 -05:00
.. code-block:: xonshcon
2015-03-08 19:06:39 -05:00
>>> touch a aa aaa aba abba aab aabb abcba
>>> ls `a(a+|b+)a`
aaa aba abba
>>> print(`a(a+|b+)a`)
['aaa', 'aba', 'abba']
>>> len(`a(a+|b+)a`)
3
This same kind of search is performed if the backticks are prefaced with ``r``.
So the following expresions are equivalent: ```test``` and ``r`test```.
2016-06-08 22:47:21 -04:00
2015-03-22 15:48:26 -04:00
Other than the regex matching, this functions in the same way as normal
2016-06-08 22:47:21 -04:00
globbing. For more information, please see the documentation for the ``re``
module in the Python standard library.
2015-03-08 19:06:39 -05:00
2016-06-04 15:36:21 -04:00
.. warning:: This backtick syntax has very different from that of Bash. In
Bash, backticks mean to run a captured subprocess ``$()``.
2015-03-08 19:06:39 -05:00
2016-06-08 22:47:21 -04:00
Normal Globbing
---------------
In subprocess mode, normal globbing happens without any special syntax.
However, the backtick syntax has an additional feature: it is available inside
of Python mode as well as subprocess mode.
Similarly to regex globbing, normal globbing can be performed (either in Python
mode or subprocess mode) by using the ``g````:
2016-06-08 22:47:21 -04:00
.. code-block:: xonshcon
>>> touch a aa aaa aba abba aab aabb abcba
>>> ls a*b*
aab aabb aba abba abcba
>>> ls g`a*b*`
aab aabb aba abba abcba
>>> print(g`a*b*`)
['aab', 'aabb', 'abba', 'abcba', 'aba']
>>> len(g`a*b*`)
5
Custom Path Searches
--------------------
In addition, if normal globbing and regular expression globbing are not enough,
xonsh allows you to specify your own search functions.
2016-06-08 22:47:21 -04:00
A search function is defined as a function of a single argument (a string) that
returns a list of possible matches to that string. Search functions can then
be used with backticks with the following syntax: ``@<name>`test```
2016-06-08 22:47:21 -04:00
2016-06-16 00:38:49 -04:00
The following example shows the form of these functions:
2016-06-08 22:47:21 -04:00
.. code-block:: xonshcon
>>> def foo(s):
2016-06-16 00:38:49 -04:00
... return [i for i in os.listdir('.') if i.startswith(s)]
>>> @foo`aa`
['aa', 'aaa', 'aab', 'aabb']
2016-06-08 22:47:21 -04:00
2015-03-08 19:06:39 -05:00
Help & Superhelp with ``?`` & ``??``
=====================================================
From IPython, xonsh allows you to inspect objects with question marks.
2016-02-15 21:11:30 +01:00
A single question mark (``?``) is used to display the normal level of help.
Double question marks (``??``) are used to display a higher level of help,
2015-03-08 19:06:39 -05:00
called superhelp. Superhelp usually includes source code if the object was
2015-03-22 15:48:26 -04:00
written in pure Python.
2015-03-08 19:06:39 -05:00
Let's start by looking at the help for the int type:
2015-03-31 01:10:19 -05:00
.. code-block:: xonshcon
2015-03-08 19:06:39 -05:00
>>> int?
Type: type
String form: <class 'int'>
Init definition: (self, *args, **kwargs)
Docstring:
int(x=0) -> integer
int(x, base=10) -> integer
Convert a number or string to an integer, or return 0 if no arguments
are given. If x is a number, return x.__int__(). For floating point
numbers, this truncates towards zero.
If x is not a number or if base is given, then x must be a string,
bytes, or bytearray instance representing an integer literal in the
given base. The literal can be preceded by '+' or '-' and be surrounded
by whitespace. The base defaults to 10. Valid bases are 0 and 2-36.
Base 0 means to interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4
<class 'int'>
Now, let's look at the superhelp for the xonsh built-in that enables
regex globbing:
2015-03-30 20:50:20 -05:00
.. code-block:: xonshcon
2015-03-08 19:06:39 -05:00
>>> __xonsh_regexpath__??
Type: function
String form: <function regexpath at 0x7fef91612950>
File: /home/scopatz/.local/lib/python3.4/site-packages/xonsh-0.1-py3.4.egg/xonsh/built_ins.py
Definition: (s)
Source:
def regexpath(s):
"""Takes a regular expression string and returns a list of file
paths that match the regex.
"""
s = expand_path(s)
return reglob(s)
<function regexpath at 0x7fef91612950>
Note that both help and superhelp return the object that they are inspecting.
2015-03-22 15:48:26 -04:00
This allows you to chain together help inside of other operations and
2015-03-08 20:52:56 -05:00
ask for help several times in an object hierarchy. For instance, let's get
help for both the dict type and its key() method simultaneously:
2015-03-08 19:06:39 -05:00
2015-03-30 20:50:20 -05:00
.. code-block:: xonshcon
2015-03-08 19:06:39 -05:00
>>> dict?.keys??
Type: type
String form: <class 'dict'>
Init definition: (self, *args, **kwargs)
Docstring:
dict() -> new empty dictionary
dict(mapping) -> new dictionary initialized from a mapping object's
(key, value) pairs
dict(iterable) -> new dictionary initialized as if via:
d = {}
for k, v in iterable:
d[k] = v
dict(**kwargs) -> new dictionary initialized with the name=value pairs
in the keyword argument list. For example: dict(one=1, two=2)
Type: method_descriptor
String form: <method 'keys' of 'dict' objects>
Docstring: D.keys() -> a set-like object providing a view on D's keys
<method 'keys' of 'dict' objects>
Of course, for subprocess commands, you still want to use the ``man`` command.
2015-03-08 19:19:30 -05:00
Compile, Evaluate, & Execute
================================
2016-06-04 15:36:21 -04:00
Like Python and Bash, xonsh provides built-in hooks to compile, evaluate,
2015-03-08 19:19:30 -05:00
and execute strings of xonsh code. To prevent this functionality from having
serious name collisions with the Python built-in ``compile()``, ``eval()``,
and ``exec()`` functions, the xonsh equivalents all append an 'x'. So for
2015-03-22 15:48:26 -04:00
xonsh code you want to use the ``compilex()``, ``evalx()``, and ``execx()``
2015-03-08 19:19:30 -05:00
functions. If you don't know what these do, you probably don't need them.
2015-03-08 17:57:12 -05:00
2015-03-08 20:06:59 -05:00
Aliases
==============================
2015-03-22 15:48:26 -04:00
Another important xonsh built-in is the ``aliases`` mapping. This is
2016-02-15 21:11:30 +01:00
like a dictionary that affects how subprocess commands are run. If you are
2016-06-04 15:36:21 -04:00
familiar with the Bash ``alias`` built-in, this is similar. Alias command
2015-03-08 20:06:59 -05:00
matching only occurs for the first element of a subprocess command.
The keys of ``aliases`` are strings that act as commands in subprocess-mode.
2016-02-15 21:11:30 +01:00
The values are lists of strings, where the first element is the command, and
2015-03-22 03:34:02 +01:00
the rest are the arguments. You can also set the value to a string, in which
case it will be converted to a list automatically with ``shlex.split``.
2015-03-08 20:06:59 -05:00
For example, the following creates several aliases for the ``git``
version control software. Both styles (list of strings and single
string) are shown:
2015-03-08 20:06:59 -05:00
.. code-block:: xonshcon
2015-03-08 20:06:59 -05:00
>>> aliases['g'] = 'git status -sb'
>>> aliases['gco'] = 'git checkout'
>>> aliases['gp'] = ['git', 'pull']
2015-03-08 20:06:59 -05:00
If you were to run ``gco feature-fabulous`` with the above aliases in effect,
the command would reduce to ``['git', 'checkout', 'feature-fabulous']`` before
being executed.
2015-03-22 15:48:26 -04:00
2016-06-11 20:52:47 -04:00
Callable Aliases
----------------
2015-03-22 15:48:26 -04:00
Lastly, if an alias value is a function (or other callable), then this
2015-03-08 20:52:56 -05:00
function is called *instead* of going to a subprocess command. Such functions
2016-06-11 20:52:47 -04:00
must have one of the following two signatures
2015-03-08 20:06:59 -05:00
2015-03-31 01:10:19 -05:00
.. code-block:: python
2015-03-08 20:06:59 -05:00
def _mycmd(args, stdin=None):
2015-03-22 15:48:26 -04:00
"""args will be a list of strings representing the arguments to this
2015-03-09 22:06:29 -05:00
command. stdin will be a string, if present. This is used to pipe
2015-03-08 20:06:59 -05:00
the output of the previous command into this one.
"""
2015-03-22 15:48:26 -04:00
# do whatever you want! Anything you print to stdout or stderr
# will be captured for you automatically. This allows callable
2015-03-10 20:29:28 -05:00
# aliases to support piping.
print('I go to stdout and will be printed or piped')
# Note: that you have access to the xonsh
2015-03-08 20:06:59 -05:00
# built-ins if you 'import builtins'. For example, if you need the
2015-03-10 20:29:28 -05:00
# environment, you could do to following:
2015-07-25 01:58:56 -06:00
import builtins
2015-03-10 20:29:28 -05:00
env = builtins.__xonsh_env__
# The return value of the function can either be None,
return
2015-03-11 01:40:48 -05:00
# a single string representing stdout
return 'I am out of here'
2015-03-22 15:48:26 -04:00
# or you can build up strings for stdout and stderr and then
2015-03-10 20:29:28 -05:00
# return a (stdout, stderr) tuple. Both of these may be
2015-03-22 15:48:26 -04:00
# either a str or None. Any results returned like this will be
2015-03-10 20:29:28 -05:00
# concatenated with the strings printed elsewhere in the function.
2015-03-08 20:06:59 -05:00
stdout = 'I commanded'
stderr = None
return stdout, stderr
# Lastly, a 3-tuple return value can be used to include an integer
# return code indicating failure (> 0 return code). In the previous
# examples the return code would be 0/success.
return (None, "I failed", 2)
2016-06-11 20:52:47 -04:00
.. code-block:: python
def _mycmd2(args, stdin, stdout, stderr):
"""args will be a list of strings representing the arguments to this
command. stdin is a read-only file-like object, and stdout and stderr
are write-only file-like objects
"""
# This form allows "streaming" data to stdout and stderr
import time
for i in range(5):
time.sleep(i)
print(i, file=stdout)
# In this form, the return value should be a single integer
# representing the "return code" of the alias (zero if successful,
# non-zero otherwise)
return 0
Adding and Removing Aliases
---------------------------
2015-03-22 15:48:26 -04:00
We can dynamically alter the aliases present simply by modifying the
2015-03-08 20:06:59 -05:00
built-in mapping. Here is an example using a function value:
2015-03-30 20:50:20 -05:00
.. code-block:: xonshcon
2015-03-08 20:06:59 -05:00
>>> def _banana(args, stdin=None):
... return ('My spoon is tooo big!', None)
>>> aliases['banana'] = _banana
2015-03-22 15:48:26 -04:00
>>> banana
2015-03-08 20:06:59 -05:00
'My spoon is tooo big!'
.. note::
Alias functions should generally be defined with a leading underscore.
Otherwise, they may shadow the alias itself, as Python variables take
precedence over aliases when xonsh executes commands.
2016-06-11 20:52:47 -04:00
Anonymous Aliases
-----------------
As mentioned above, it is also possible to treat functions outside this mapping
as aliases, by wrapping them in ``@()``. For example:
.. code-block:: xonshcon
>>> @(_banana)
'My spoon is tooo big!'
>>> echo "hello" | @(lambda args, stdin=None: stdin.strip() + args[0]) world
hello world
Foreground-only Aliases
-----------------------
Usually, callable alias commands will be run in a separate thread so that users
they may be run in the background. However, some aliases may need to be
executed on the thread that they were called from. This is mostly useful for
debuggers and profilers. To make an alias run in the foreground, decorate its
function with the ``xonsh.proc.foreground`` decorator.
2016-02-04 21:48:59 -05:00
.. code-block:: python
from xonsh.proc import foreground
@foreground
def _mycmd(args, stdin=None):
2016-02-04 21:48:59 -05:00
return 'In your face!'
aliases['mycmd'] = _mycmd
2015-03-22 15:52:02 -04:00
Aliasing is a powerful way that xonsh allows you to seamlessly interact to
2015-03-22 15:48:26 -04:00
with Python and subprocess.
2015-03-08 20:47:35 -05:00
Up, Down, Tab
==============
2015-03-22 15:48:26 -04:00
The up and down keys search history matching from the start of the line,
2015-03-08 20:47:35 -05:00
much like they do in the IPython shell.
2016-06-02 12:17:27 -04:00
Tab completion is present as well. By default, in Python-mode you are able to
complete based on the variable names in the current builtins, globals, and
locals, as well as xonsh languages keywords & operator, files & directories,
and environment variable names. In subprocess-mode, you additionally complete
2016-06-04 15:36:21 -04:00
on the names of executable files on your ``$PATH``, alias keys, and full Bash
completion for the commands themselves.
2015-03-08 20:47:35 -05:00
2016-06-02 12:08:13 -04:00
xonsh also provides a means of modifying the behavior of the tab completer. More
detail is available on the `Tab Completion page <tutorial_completers.html>`_.
2015-03-08 20:47:35 -05:00
2015-04-03 21:49:31 -04:00
Customizing the Prompt
======================
2016-06-07 17:50:40 -04:00
Customizing the prompt by modifying ``$PROMPT`` is probably the most common
reason for altering an environment variable.
.. note:: Note that the ``$PROMPT`` variable will never be inherited from a
parent process (regardless of whether that parent is a foreign shell
or an instance of xonsh).
The ``$PROMPT`` variable can be a string, or it can be a function (of no
arguments) that returns a string. The result can contain keyword arguments,
which will be replaced automatically:
2015-04-03 21:49:31 -04:00
.. code-block:: xonshcon
>>> $PROMPT = '{user}@{hostname}:{cwd} > '
snail@home:~ > # it works!
snail@home:~ > $PROMPT = lambda: '{user}@{hostname}:{cwd} >> '
2015-04-03 21:49:31 -04:00
snail@home:~ >> # so does that!
2015-05-20 14:43:20 -04:00
2015-04-03 21:49:31 -04:00
By default, the following variables are available for use:
2016-02-20 15:24:19 -05:00
2015-04-03 21:49:31 -04:00
* ``user``: The username of the current user
* ``hostname``: The name of the host computer
2016-05-28 17:35:56 -04:00
* ``cwd``: The current working directory, you may use ``$DYNAMIC_CWD_WIDTH`` to
set a maximum width for this variable.
2015-11-29 20:38:23 -05:00
* ``short_cwd``: A shortened form of the current working directory; e.g.,
``/path/to/xonsh`` becomes ``/p/t/xonsh``
2015-08-13 08:54:47 -04:00
* ``cwd_dir``: The dirname of the current working directory, e.g. ``/path/to`` in
2015-08-04 18:04:21 -05:00
``/path/to/xonsh``.
2015-08-13 08:54:47 -04:00
* ``cwd_base``: The basename of the current working directory, e.g. ``xonsh`` in
2015-08-04 18:04:21 -05:00
``/path/to/xonsh``.
2015-04-03 21:49:31 -04:00
* ``curr_branch``: The name of the current git branch (preceded by space),
if any.
2015-05-13 22:52:49 -04:00
* ``branch_color``: ``{BOLD_GREEN}`` if the current git branch is clean,
2016-06-09 22:52:41 -04:00
otherwise ``{BOLD_RED}``. This is yellow if the branch color could not be
determined.
* ``branch_bg_color``: Like, ``{branch_color}``, but sets a background color
instead.
* ``prompt_end``: `#` if the user has root/admin permissions `$` otherwise
* ``current_job``: The name of the command currently running in the
foreground, if any.
2015-04-03 21:49:31 -04:00
You can also color your prompt easily by inserting keywords such as ``{GREEN}``
or ``{BOLD_BLUE}``. Colors have the form shown below:
2015-05-20 14:43:20 -04:00
2016-02-20 15:24:19 -05:00
* ``NO_COLOR``: Resets any previously used color codes
2016-02-29 21:18:22 -05:00
* ``COLORNAME``: Inserts a color code for the following basic colors,
2016-02-20 15:24:19 -05:00
which come in regular (dark) and intense (light) forms:
2016-02-29 21:18:22 -05:00
- ``BLACK`` or ``INTENSE_BLACK``
2016-02-20 15:24:19 -05:00
- ``RED`` or ``INTENSE_RED``
- ``GREEN`` or ``INTENSE_GREEN``
- ``YELLOW`` or ``INTENSE_YELLOW``
- ``BLUE`` or ``INTENSE_BLUE``
- ``PURPLE`` or ``INTENSE_PURPLE``
- ``CYAN`` or ``INTENSE_CYAN``
- ``WHITE`` or ``INTENSE_WHITE``
2016-02-29 21:18:22 -05:00
* ``#HEX``: A ``#`` before a len-3 or len-6 hex code will use that
hex color, or the nearest approximation that that is supported by
2016-02-20 15:24:19 -05:00
the shell and terminal. For example, ``#fff`` and ``#fafad2`` are
both valid.
* ``BACKGROUND_`` may be added to the begining of a color name or hex
color to set a background color. For example, ``BACKGROUND_INTENSE_RED``
and ``BACKGROUND_#123456`` can both be used.
* ``bg#HEX`` or ``BG#HEX`` are shortcuts for setting a background hex color.
Thus you can set ``bg#0012ab`` or the uppercase version.
* ``BOLD_`` is a prefix qualifier that may be used with any foreground color.
For example, ``BOLD_RED`` and ``BOLD_#112233`` are OK!
2016-02-29 21:18:22 -05:00
* ``UNDERLINE_`` is a prefix qualifier that also may be used with any
2016-02-20 15:24:19 -05:00
foreground color. For example, ``UNDERLINE_GREEN``.
2016-02-29 21:18:22 -05:00
* Or any other combination of qualifiers, such as
``BOLD_UNDERLINE_INTENSE_BLACK``, which is the most metal color you
2016-02-20 15:24:19 -05:00
can use!
2015-04-03 21:49:31 -04:00
You can make use of additional variables beyond these by adding them to the
``FORMATTER_DICT`` environment variable. The values in this dictionary
2015-04-03 21:49:31 -04:00
should be strings (which will be inserted into the prompt verbatim), or
functions of no arguments (which will be called each time the prompt is
generated, and the results of those calls will be inserted into the prompt).
For example:
2016-05-20 17:58:50 -04:00
.. code-block:: console
2015-04-03 21:49:31 -04:00
snail@home ~ $ $FORMATTER_DICT['test'] = "hey"
snail@home ~ $ $PROMPT = "{test} {cwd} $ "
2015-05-20 14:43:20 -04:00
hey ~ $
2015-04-03 21:49:31 -04:00
hey ~ $ import random
hey ~ $ $FORMATTER_DICT['test'] = lambda: random.randint(1,9)
2015-05-20 14:43:20 -04:00
3 ~ $
5 ~ $
2 ~ $
8 ~ $
2015-04-03 21:49:31 -04:00
If a function in ``$FORMATTER_DICT`` returns ``None``, the ``None`` will be
interpreted as an empty string.
Environment variables and functions are also available with the ``$``
prefix. For example:
2016-05-20 17:58:50 -04:00
.. code-block:: console
snail@home ~ $ $PROMPT = "{$LANG} >"
en_US.utf8 >
Executing Commands and Scripts
==============================
When started with the ``-c`` flag and a command, xonsh will execute that command
and exit, instead of entering the command loop.
.. code-block:: bash
bash $ xonsh -c "echo @(7+3)"
10
Longer scripts can be run either by specifying a filename containing the script,
or by feeding them to xonsh via stdin. For example, consider the following
2015-03-31 01:10:19 -05:00
script, stored in ``test.xsh``:
2015-03-31 01:10:19 -05:00
.. code-block:: xonsh
#!/usr/bin/env xonsh
2015-05-20 14:43:20 -04:00
2015-04-03 22:15:13 -04:00
ls
2015-05-20 14:43:20 -04:00
print('removing files')
2015-04-03 22:15:13 -04:00
rm `file\d+.txt`
2015-05-20 14:43:20 -04:00
2015-04-03 22:15:13 -04:00
ls
2015-05-20 14:43:20 -04:00
2015-03-22 15:48:26 -04:00
print('adding files')
# This is a comment
for i, x in enumerate("xonsh"):
2016-05-20 17:58:50 -04:00
echo @(x) > @("file{0}.txt".format(i))
2015-05-20 14:43:20 -04:00
print($(ls).replace('\n', ' '))
This script could be run by piping its contents to xonsh:
.. code-block:: bash
2015-04-03 22:15:13 -04:00
bash $ cat test.xsh | xonsh
file0.txt file1.txt file2.txt file3.txt file4.txt test_script.sh
removing files
test_script.sh
adding files
2015-03-22 15:48:26 -04:00
file0.txt file1.txt file2.txt file3.txt file4.txt test_script.sh
or by invoking xonsh with its filename as an argument:
.. code-block:: bash
2015-04-03 22:15:13 -04:00
bash $ xonsh test.xsh
file0.txt file1.txt file2.txt file3.txt file4.txt test_script.sh
removing files
test_script.sh
adding files
file0.txt file1.txt file2.txt file3.txt file4.txt test_script.sh
xonsh scripts can also accept arguments. These arguments are made available to
the script in two different ways:
2015-04-01 20:01:35 -05:00
#. In either mode, as individual variables ``$ARG<n>`` (e.g., ``$ARG1``)
2015-03-23 01:15:48 -05:00
#. In Python mode only, as a list ``$ARGS``
2015-03-22 15:48:26 -04:00
For example, consider a slight variation of the example script from above that
operates on a given argument, rather than on the string ``'xonsh'`` (notice how
``$ARGS`` and ``$ARG1`` are used):
2016-05-11 01:55:53 -04:00
2015-03-31 01:10:19 -05:00
.. code-block:: xonsh
#!/usr/bin/env xonsh
2015-05-20 14:43:20 -04:00
print($ARGS)
2015-05-20 14:43:20 -04:00
2015-04-03 22:15:13 -04:00
ls
2015-05-20 14:43:20 -04:00
print('removing files')
2015-04-03 22:15:13 -04:00
rm `file\d+.txt`
2015-05-20 14:43:20 -04:00
2015-04-03 22:15:13 -04:00
ls
2015-05-20 14:43:20 -04:00
print('adding files')
# This is a comment
for i, x in enumerate($ARG1):
2016-05-20 17:58:50 -04:00
echo @(x) > @("file{0}.txt".format(i))
2015-05-20 14:43:20 -04:00
print($(ls).replace('\n', ' '))
print()
2016-05-11 01:55:53 -04:00
.. code-block:: bash
2015-04-03 22:15:13 -04:00
bash $ xonsh test2.xsh snails
['test_script.sh', 'snails']
file0.txt file1.txt file2.txt file3.txt file4.txt file5.txt test_script.sh
removing files
test_script.sh
adding files
file0.txt file1.txt file2.txt file3.txt file4.txt file5.txt test_script.sh
2015-03-22 15:48:26 -04:00
bash $ echo @(' '.join($(cat @('file%d.txt' % i)).strip() for i in range(6)))
s n a i l s
2015-03-08 20:47:35 -05:00
2016-02-29 21:18:22 -05:00
Additionally, if the script should exit if a command fails, set the
environment variable ``$RAISE_SUBPROC_ERROR = True`` at the top of the
file. Errors in Python mode will already raise exceptions and so this
2016-02-15 21:11:30 +01:00
is roughly equivalent to Bash's ``set -e``.
2016-02-04 21:48:59 -05:00
Furthermore, you can also toggle the ability to print source code lines with the
2016-02-29 21:18:22 -05:00
``trace on`` and ``trace off`` commands. This is roughly equivelent to
2016-02-04 21:48:59 -05:00
Bash's ``set -x`` or Python's ``python -m trace``, but you know, better.
2016-01-24 12:08:50 -05:00
2015-03-29 18:56:25 -05:00
Importing Xonsh (``*.xsh``)
==============================
2015-04-01 20:01:35 -05:00
You can import xonsh source files with the ``*.xsh`` file extension using
2016-02-15 21:11:30 +01:00
the normal Python syntax. Say you had a file called ``mine.xsh``, you could,
therefore, perform a Bash-like source into your current shell with the
2015-03-29 18:56:25 -05:00
following:
2015-03-31 01:10:19 -05:00
.. code-block:: xonsh
2015-03-29 18:56:25 -05:00
from mine import *
2015-03-08 20:47:35 -05:00
That's All, Folks
======================
2015-05-16 01:37:06 -04:00
To leave xonsh, hit ``Ctrl-D``, type ``EOF``, type ``quit``, or type ``exit``.
2016-02-15 21:11:30 +01:00
On Windows, you can also type ``Ctrl-Z``.
2015-03-08 20:47:35 -05:00
2015-03-31 01:10:19 -05:00
.. code-block:: xonshcon
2015-03-08 20:47:35 -05:00
>>> exit
Now it is your turn.