on 6d45ede help sign in
356 lines 11 kB history raw
1---
2navhome: /docs
3sort: 8
4title: From Unix
5---
7<div class="row">
8<div class="col-md-8">
10# Using Urbit from Unix
12With `urb` at your Unix command line, you can execute hoon, run
13dojo commands, and more. Additionally, with `fuse`, you can
14inspect the urbit namespace.
16</div>
17</div>
19## Installation
21These commands are in the a [separate
22repo](https://github.com/urbit/urb). Clone this repo to get the
23commands.
25You'll also need the `requests` and `fuse` libraries for python.
26If you have `pip`, you can just run:
28```
29pip install requests fuse-python
30```
32Otherwise, on Ubuntu, run:
34```
35apt-get install python-requests python-fuse
36```
38Then you can either run the python commands from the git repo, or
39put them somewhere in your path.
41## `urb`
43`urb` transfers data from a source to a sink. Examples of data
44sources include literal data, a file, a URL, or some
45tranformation of another source. Examples of data sinks are
46stdout, output file, POST request, or dojo command.
48Here are some examples. This takes the literal data "hello
49world" and sends it to stdout (the default sink).
51 urb --data 'hello world'
53Let's run some hoon code at the dojo.
55 urb --dojo '(add 2 2)'
57Let's convert a markdown file to html.
59 urb --data @@file.md -m md -m html
61Mount the `%home` desk. This syncs the `home` desk into the pier
62directory.
64 urb --dojo '+hood/mount /=home=' --app hood
66### Sources
68Sources can be any of the following:
70- `-d, --dojo command` runs a dojo command. This is commonly
71 naked hoon code, but it can also be a generator, or any of the
72 other ways the dojo gets data.
74- `-D, --data text` is literal text data, as a cord.
76- `-c, --clay path` pulls data from Urbit's filesystem.
78- `-u, --url url` pulls data from a URL.
80- `-m, --mark mark source` converts the output from another source to
81 a new 'mark' (datatype).
83- `-H, --hoon code source` transforms the output of another
84 source by running it through some hoon code.
86- `[source-0 source-1 ...]`. Sources can be combined into tuples
87 of different sources.
89Any of the arguments to a source (except in the "compound
90sources" `--mark` and `--hoon`) can be replaced by `-` to
91represent stdin or `@@filename` to pull data in from a Unix file.
92Thus, `urb [-D @@file1 -D - -D @@file2]` is equivalent to Unix's
93`cat file1 - file2`.
95Additionally, if no source is specified, `--data -` (stdin as
96literal text data) is assumed.
98### Sinks
100- `-s, --stdout` outputs to stdout. This is the default.
102- `-f, --output-file path` writes to a unix file.
104- `-C, --output-clay path` writes to Urbit's filesystem.
106- `-U, --output-url url` sends a POST request with the data to
107 the URL.
109- `-p, --app app` sends the data to an urbit app.
111- `-x, --command` outputs to a literal dojo command.
113## `fuse`
115Urbit's namespace is accessible through the `fuse` command.
116`fuse` takes all the normal FUSE arguments, which you can see
117with `fuse -h`. Generally, you just run `fuse MOUNT-POINT`.
119When accessing the namespace through `fuse`, everything is
120read-only. If you want to write to Clay, mount a desk, as
121described above.
123Let's look first in the Clay portion of the Urbit namespace.
124Assume we've mounted to `./pt`.
126 $ ls ./pt/c/=/=/=
127 app arvo gen lib mar ren sec sur web
128 $ ls ./pt/c/=/=/=/arvo
129 ames behn clay dill eyre ford gall hoon zuse
131Those `=`s aren't decorative. The first `=` means "current
132ship", the second "current desk", and the third "current
133revision". Let's try something a little more exciting.
135This runs the Unix `diff` command on the first and current
136versions of the `app/gh/hoon` file, showing all the changes we've
137made to the file.
139```
140$ diff pt/c/=/=/{1,=}/app/gh/hoon
14173c73,75
142< (malt (turn issues |=(issue:gh [(rsh 3 2 (scot %ui number)) ~])))
143---
144> %- malt ^- (list {@ta $~})
145> :- [%gh-list-issues ~]
146> (turn issues |=(issue:gh [(rsh 3 2 (scot %ui number)) ~]))
14792c94,101
148< read-y=(read-get /issues)
149---
150> read-y=(read-static %gh-list-issues ~)
151> sigh-x=sigh-list-issues-x
152> sigh-y=sigh-list-issues-y
153> ==
154> ^- place :: /issues/mine/<mark>
155> :* guard={$issues $mine @t $~}
156> read-x=read-null
157> read-y=|=(pax/path [ost %diff %arch `0vsen.tinel ~])
158126c135
159< ^- place :: /issues/by-repo/<user>/<repo>
160---
161> ^- place :: /issues/by-repo/<user>/<repo>/<number>
162131c140,146
163< read-y=(read-static ~)
164---
165> ^= read-y
166> |= pax/path
167> %. pax
168> ?: ((sane %tas) -.+>+>.pax)
169> (read-static ~)
170> (read-static %gh-issue ~)
171> ::
172137a153,159
173> sigh-y=sigh-strange
174> ==
175> ^- place :: /issues/by-repo/<u>/<r>/<n>/<mark>
176> :* guard={$issues $by-repo @t @t @t @t $~}
177> read-x=read-null
178> read-y=|=(pax/path [ost %diff %arch `0vsen.tinel ~])
179> sigh-x=sigh-strange
180```
182Urbit's namespace is not just revisioned, but global. Here's a
183diff of our version of `arvo/gall/hoon` compared to the one on
184the `~bud` urbit.
186```
187$ diff pt/c/{~bud,=}/=/=/arvo/gall/hoon
1882d1
189<
190640a640,644
191> =+ ?. ?=($x ren)
192> [mar=%$ tyl=tyl]
193> =+ `path`(flop tyl)
194> ?> ?=(^ -)
195> [mar=i tyl=(flop t)]
196643c647
197< ((slog leaf+"peek find fail" >tyl< ~) [~ ~])
198---
199> ((slog leaf+"peek find fail" >tyl< >mar< ~) [~ ~])
200654a659,660
201> ?. =(mar p.q.caz)
202> [~ ~]
2031308a1315,1316
204> ?. ?=(^ tyl)
205> ~
206```
208Besides Clay, the namespace contains Gall apps. One common usage
209of the app namespace is to expose APIs. For example, if you
210start the `%gh` app (`|start %gh`), you can do things like `cat`
211an issue from a repository.
213```
214$ cat pt/g/=/gh/=/issues/by-repo/philipcmonktest/testing/7/txt
215title: big news! (#7)
216state: open
217creator: philipcmonktest
218created-at: 2016-03-24T22:27:33Z
219assignee: philipcmonktest
220labels: invalid, wontfix, help wanted
221comments: 0
222url: https://api.github.com/repos/philipcmonktest/testing/issues/7
224Yup, that's it. i mean, maybe it's a bit longer than that.
226But you get the point, right?
228Code `is` cool!
229```
231Or all open issues for a repository.
233```
234$ cat pt/g/=/gh/=/issues/by-repo/philipcmonktest/testing/txt
235title: i found a bug! (#11)
236state: open
237creator: philipcmonktest
238created-at: 2016-04-14T23:14:49Z
239assignee: none
240labels:
241comments: 1
242url: https://api.github.com/repos/philipcmonktest/testing/issues/11
245----------------------------------------
246title: more newz (#8)
247state: open
248creator: philipcmonktest
249created-at: 2016-03-24T22:29:16Z
250assignee: none
251labels:
252comments: 4
253url: https://api.github.com/repos/philipcmonktest/testing/issues/8
255Yup, that's it. i mean, maybe it's a bit longer than that.
257But you get the point, right?
259Code `is` cool!
260----------------------------------------
261title: big news! (#7)
262state: open
263creator: philipcmonktest
264created-at: 2016-03-24T22:27:33Z
265assignee: philipcmonktest
266labels: invalid, wontfix, help wanted
267comments: 0
268url: https://api.github.com/repos/philipcmonktest/testing/issues/7
270Yup, that's it. i mean, maybe it's a bit longer than that.
272But you get the point, right?
274Code `is` cool!
275----------------------------------------
276title: something different (#4)
277state: open
278creator: philipcmonktest
279created-at: 2016-01-26T21:45:08Z
280assignee: philipcmonktest
281labels: duplicate, help wanted, question, bug
282comments: 1
283url: https://api.github.com/repos/philipcmonktest/testing/issues/4
284```
286Don't like the textual format? How about we get the raw JSON
287(and prettyprint it).
289```
290$ cat pt/g/=/gh/=/issues/by-repo/philipcmonktest/testing/7/json | python -m json.tool
292 "assignee": {
293 "avatar_url": "https://avatars.githubusercontent.com/u/16787461?v=3",
294 "events_url": "https://api.github.com/users/philipcmonktest/events{/privacy}",
295 "followers_url": "https://api.github.com/users/philipcmonktest/followers",
296 "following_url": "https://api.github.com/users/philipcmonktest/following{/other_user}",
297 "gists_url": "https://api.github.com/users/philipcmonktest/gists{/gist_id}",
298 "gravatar_id": "",
299 "html_url": "https://github.com/philipcmonktest",
300 "id": 16787461,
301 "login": "philipcmonktest",
302 "organizations_url": "https://api.github.com/users/philipcmonktest/orgs",
303 "received_events_url": "https://api.github.com/users/philipcmonktest/received_events",
304 "repos_url": "https://api.github.com/users/philipcmonktest/repos",
305 "site_admin": false,
306 "starred_url": "https://api.github.com/users/philipcmonktest/starred{/owner}{/repo}",
307 "subscriptions_url": "https://api.github.com/users/philipcmonktest/subscriptions",
308 "type": "User",
309 "url": "https://api.github.com/users/philipcmonktest"
310 },
311 "body": "Yup, that's it. i mean, maybe it's a bit longer than that.\r\n\r\nBut you get the point, right?\r\n\r\nCode `is` cool!",
312 "closed_at": null,
313 "closed_by": null,
314 "comments": 0,
315 "comments_url": "https://api.github.com/repos/philipcmonktest/testing/issues/7/comments",
316 "created_at": "2016-03-24T22:27:33Z",
317 "events_url": "https://api.github.com/repos/philipcmonktest/testing/issues/7/events",
318 "html_url": "https://github.com/philipcmonktest/testing/issues/7",
319 "id": 143377108,
320 "labels": [
321 {
322 "color": "ffffff",
323 "name": "wontfix",
324 "url": "https://api.github.com/repos/philipcmonktest/testing/labels/wontfix"
325 }
326 ],
327 "labels_url": "https://api.github.com/repos/philipcmonktest/testing/issues/7/labels{/name}",
328 "locked": false,
329 "milestone": null,
330 "number": 7,
331 "repository_url": "https://api.github.com/repos/philipcmonktest/testing",
332 "state": "open",
333 "title": "big news!",
334 "updated_at": "2016-03-24T22:27:33Z",
335 "url": "https://api.github.com/repos/philipcmonktest/testing/issues/7",
336 "user": {
337 "avatar_url": "https://avatars.githubusercontent.com/u/16787461?v=3",
338 "events_url": "https://api.github.com/users/philipcmonktest/events{/privacy}",
339 "followers_url": "https://api.github.com/users/philipcmonktest/followers",
340 "following_url": "https://api.github.com/users/philipcmonktest/following{/other_user}",
341 "gists_url": "https://api.github.com/users/philipcmonktest/gists{/gist_id}",
342 "gravatar_id": "",
343 "html_url": "https://github.com/philipcmonktest",
344 "id": 16787461,
345 "login": "philipcmonktest",
346 "organizations_url": "https://api.github.com/users/philipcmonktest/orgs",
347 "received_events_url": "https://api.github.com/users/philipcmonktest/received_events",
348 "repos_url": "https://api.github.com/users/philipcmonktest/repos",
349 "site_admin": false,
350 "starred_url": "https://api.github.com/users/philipcmonktest/starred{/owner}{/repo}",
351 "subscriptions_url": "https://api.github.com/users/philipcmonktest/subscriptions",
352 "type": "User",
353 "url": "https://api.github.com/users/philipcmonktest"
354 }
356```