top of page
Escapes

Marcel can execute host executables, and integrate them into pipelines. For example, there is no cat operator in marcel, but there is a useful Linux operator by that name, so this works:

M 0.18.3 jao@loon ~/git/marcel$ cat ~/.gitconfig
[user]
   name = Jack Orenstein
   email = jao@geophile.com
[core]
   editor = emacs
[cola]
   spellcheck = false
[credential]
   helper = store

If you want to be explicit about using an executable (and not an operator), you can use the bash operator. So, for example, if you really want to use the host operating system's pwd command, instead of marcel's pwd operator, you can do so as follows:

M 0.18.3 jao@loon ~/git/marcel$ bash pwd
/home/jao/git/marcel

Mixing host executables and marcel operators in the same pipeline works well. At the boundary between the two, strings are passed. Between marcel operators, Python values are passed.

For example, this command, which combines operators and executables, lists the usernames of users whose shell is /bin/bash. map and select are marcel operators, while cat, xargs and echo are Linux executables.

M 0.18.3 jao@loon ~/git/marcel$ cat /etc/passwd \
M +$    | map (line: line.split(':')) \
M +$    | select (*line: line[-1] == '/bin/bash') \
M +$    | map (username, *_: username) \
M +$    | xargs echo
root jao postgres

  • cat /etc/passwd: Obtain the contents of the file. Lines are piped to subsequent commands.

  • map (line: line.split(':')): Split the lines at the : separators, yielding 7-tuples.

  • select (*line: line[-1] == '/bin/bash'): select those lines in which the last field is /bin/bash.

  • map (username, *_: username): Keep the username field of each input tuple.

  • xargs echo: Combine the incoming usernames into a single line, which is printed to stdout.


Another kind of escape is the sudo operator. It works very much like the host operating system's sudo command, allowing you to execute some commands that you would otherwise not be permitted to execute. You configure marcel's sudo in the same way as that of the host OS, (e.g. editing /etc/sudoers). One difference is that marcel's sudo operator takes a pipeline argument, instead of a host OS command. For example, to examine root's .ssh directory:

M 0.18.3 jao@loon ~/git/marcel$ ls /root/.ssh
No qualifying paths, (possibly due to permission errors): ['/root/.ssh']
M 0.18.3 jao@loon ~/git/marcel$ sudo (| ls /root/.ssh |)
drwx------   root   root       4096   2023 Oct 25 04:31:14   .
-rw-------   root   root        389   2023 Aug 03 10:01:11   authorized_keys
-rw-------   root   root       3369   2023 Aug 02 22:24:46   id_rsa
-rw-r--r--   root   root        735   2023 Aug 02 22:24:46   id_rsa.pub
-rw-------   root   root       1170   2023 Aug 02 10:12:46   known_hosts
-rw-------   root   root        948   2023 Aug 02 10:12:42   known_hosts.old

bottom of page