HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
oils-for-unix
oils
Python2016–2025
oils-for-unix / oils

oils

Oils is our upgrade path from bash to a better language and runtime. It's also for Python and JavaScript users who avoid shell!

35Distinct people
225Mentions
1Explicit recommenders
3.4KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Oils is our upgrade path from bash to a better language and runtime. It's also for Python and JavaScript users who avoid shell!

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

There are Usenix papers on bash and ksh -- I archived the ksh one here: http://www.oilshell.org/archive/ksh-usenix.pdf The surprising thing to me is that ksh was Lua-like in…

chubot used a recommendation phrase. 4 indexed comments match. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 8–Nov 15 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/15/2026, 2:59:58 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year225 dated mentions

Observed mentions: 2016-11-26 10:24:57 UTC to 2025-11-06 22:34:08 UTC.

02040602016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments20162017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 13 mentions; 0 submissions, 13 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 9 mentions; 0 submissions, 9 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 27 mentions; 2 submissions, 25 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 52 mentions; 3 submissions, 49 comments20202021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 41 mentions; 2 submissions, 39 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 27 mentions; 3 submissions, 24 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 16 mentions; 1 submissions, 15 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 17 mentions; 2 submissions, 15 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 20 mentions; 2 submissions, 18 comments2025

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC303
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC13013
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC909
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC27225
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC52349
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC41239
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC27324
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC16115
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC17215
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC20218

What Hacker News says

13 sources
Data frame is fairly well defined, but it's a common source of confusion. In a data frame, the columns are of heterogeneous types (string, integer, bool, double, factor or "enum", etc.). In a vector/matrix, every cell has the same type. A short way to understand it is that R and Matlab aren't the same thing. They are not substitutes for one another. In R, the core type is the data frame. In Matlab, it is the matrix, of which a 2D array is a special case. (Both Matlab and R have grown some of the others' functionality, but it's not good at all. You can tell which one is primary.) Another way to say it: Julia at its core isn't an R replacement; it's a Matlab replacement. Apparently, the representation of missing values was a problem for DataFrames.jl. Whether or not individual entries in a vector are "nullable" has a large impact on
Read the rest
how you write vectorized mathematical operations and how well it performs. And if you notice that data frames sound like SQL tables, well that's exactly why these Apache projects are converging/overlapping :) They are coming from different points of view, but they have the same underlying data model. One of my slogans is that "R is the only language without the ORM problem", because its native data model matches the data model of a relational database. I'm designing a shell which will feature data frames (eventually, probably not for a year or more): https://github.com/oilshell/oil/wiki/Oil-and-the-R-Language SQL is a very limited language, with essentially no capabilities for abstraction. Writing programs using the relational model in a Turing-complete language like R or Python is very powerful.
In Do we need a third Apache project for columnar data representation?
chubot·Aug 18, 2017Recommendation phrase
I recommend using plain shell scripts. Each .PHONY target is a simple shell function, and then the last line of the script is "$@", which means run function $1 with parameters $2 to $n. So instead of 'make test', I just use './test.sh all', or './test.sh foo'. The test script can invoke make. The idea is that 'dataflow' parts are done in Make, and the imperative parts are done in shell. This works out fairly well if you're disciplined about it. The only point of Makefiles is to support quick incremental builds. If there's no incrementality, then you might as well use shell. (Note: whenever you use Make, you're using shell by definition. There's no possibility of only using Make. So I take Make out of the picture where it's not necessary.) For example, all the instructions here are of the form 'foo.sh ACTION': https://github.com/o
Read the rest
ilshell/oil/wiki/Contributing Pretty much every shell script in the repo uses "the argv dispatch pattern"... I've been meaning to write a blog post about that pattern, i.e. using functions with the last line as "$@". https://github.com/oilshell/oil
In Afraid of Makefiles? Don't be
I saved the recent "Terminal and Shell Performance" article [1] in the Wiki for my shell [2], and I saw that I had saved this great article on a similar subject (editor lag vs. terminal lag). In this article I examine human- and machine aspects of typing latency (“typing lag”) and present experimental data on latency of popular text / code editors. The article is inspired by my work on implementing “zero-latency typing” in IntelliJ IDEA. [1] https://news.ycombinator.com/item?id=14798211 [2] https://github.com/oilshell/oil/wiki/Interactive-Shell
In Typing with Pleasure
Not particularly creative, but I'm using it to generate this blog: http://www.oilshell.org/blog/ (Makefile not available) and build a Python program into a single file (stripped-down Python interpreter + embedded bytecode): https://github.com/oilshell/oil/blob/master/Makefile Although generally I prefer shell to Make. I just use Make for the graph, while shell has most of the logic. Although honestly Make is pretty poor at specifying a build graph.
In Ask HN: In what creative ways are you using Makefiles?
Yes, this great article is all about how the maintainer of Bash regrets that it uses a parser generator (yacc): http://www.aosabook.org/en/bash.html I've mentioned this here before, but I was able to parse bash almost entirely up front, without interleaving parsing and execution. The first half of my blog [1] is about this. To make a long story short, I use four interleaved parsers, and they ask the lexer to change state at the appropriate points. It's three separate recursive descent parsers, and then a Pratt parser for C-style arithmetic expressions. It works very nicely, and surprisingly the algorithm is efficient, requiring only two tokens of lookahead: http://www.oilshell.org/blog/2016/11/17.html Aside from lookahead, the lexer reads the text exactly once, not 2, 3, or 4 times. There are two things you can't parse up front that I k
Read the rest
now of: - Associative array syntax, but this is bash 4.0-specific: http://www.oilshell.org/blog/2016/10/20.html - A crazy instance of runtime parsing of arithmetic expressions inside strings, AFTER variable substitution: https://github.com/oilshell/oil/issues/3 (all shells I tested implement this, not just bash) Also there is one issue that would require arbitrary lookahead: - Bash does arbitrary lookahead to distinguish $((1+2)) and $((echo hi)), the former being arithmetic, and the latter being a subshell inside a command sub, but it's not required by POSIX: http://www.oilshell.org/blog/2016/11/18.html In bash, Brace substitution is really metaprogramming which can be done at parse time. You can manipulate program fragments, e.g. a{b,$((i++)),c,d}e, and it doesn't rely on any program input. In ksh, brace substitution is done AFTER variable substitution, so it's another level of runtime parsing. Globbing is done AFTER variable substitution in all shells. But yes, lex and yacc are totally unsuitable for parsing shell. It's unbelievably awkward to express, and results in more code, because the parser has to be used for interactive input (the $PS2 problem), and it also should be used for command completion, e.g completing something like 'echo $(ls /b<TAB>...' . It also forces you into parsing at runtime, as far as I can tell. The yylex() interface involves a lot of globals and the generated parsers probably don't compose as I would like. [1] http://www.oilshell.org/blog/
In Writing a Unix Shell – Part II
I was going to write that I don't have a good pointer, but actually I think the idea is basically the "onion architecture" or "clean architecture". I don't recall if I watched all of this talk, but in general I like Brandon Rhodes' PyCon talks : https://www.youtube.com/watch?v=DJtef410XaM http://rhodesmill.org/brandon/slides/2014-07-pyohio/clean-ar... I don't come from a Java background, but I think that many of these ideas originated in the Java community. They came to Python later (if at all), and it's a little funny to see Go struggling with the same thing. I think I came at it from more of a functional programming perspective, and the style gradually converged with what people were thinking about OOP. I'm not actually of all the details about "clean architecture" and "onion architecture", but they are definitely related to dependen
Read the rest
cy injection. Basically all your effects and state can be instantiated on the "outside" in main() and passed INWARD. But I don't believe it necessarily has to be pure. I encapsulate all my state, but I don't encapsulate all my side effects, like printing to the screen. Some people appeared to like this comment, which is somewhat related: https://news.ycombinator.com/item?id=11841893 I'm not sure how much this will help, but here is 12K+ lines of code I wrote with zero globals: https://github.com/oilshell/oil The main directories to look at are core/ and osh/. The main program imports a lot of stuff and wires it together: https://github.com/oilshell/oil/blob/master/bin/oil.py (There is a bunch of surface messiness, but the architecture is sound.) I've also written even larger programs with zero globals. Also, I believe that web frameworks are some of the worst offenders in terms of preventing you from using this style. I don't think I've seen a single web framework that made the handlers easily testable. I think you may be fighting against the grain in some parts of the Python world using this style... I can do it in certain projects because I'm writing most of the code from scratch, and forking some dependencies.
In A theory of modern Golang
I don't know anything about PTYs either, since my shell is mostly a batch program like Perl right now. I'm viewing it first from a programming language perspective. As mentioned, I'm deferring to GNU readline for interactive features. I'd be interested in what problems you had with PTYs and what module you used? Are PTYs standardized by POSIX? It feels like you should be able to write a shell against only POSIX APIs (and ANSI C). I'd also be interested to see your shell. There are a bunch of alternative shells and POSIX shell implementations here: https://github.com/oilshell/oil/wiki/ExternalResources EDIT: I saw the sibling comment linking to https://github.com/lmorg/murex. Taking a look! A few months ago I started a thread with the authors of elvish, oh, mash, and NGS shells to exchange ideas. (elvish and oh are also written in G
Read the rest
o.) I didn't know about your shell or I would have included you!
In Writing a Unix Shell
A context-free grammar, besides making things a lot simpler, means that IDEs can do syntax highlighting without integrating most of a compiler front end. As a result, third-party tools become much more likely to exist. This statement feels imprecise in a couple ways. It seems to imply that some IDEs actually use context-free grammars for syntax highlighting? Which ones? As far as I can tell, Vim and Textmate bundles (i.e. what Github uses for syntax highlighting) don't use anything close to a context-free grammar for their syntax highlighting models. They are more like ad hoc lexers -- a collection of rules and regular expressions. Certainly an editor doesn't want to parse the entire file to highlight text, because it has to potentially re-highlight at every keystroke. Also, you want to be able to highlight malformed programs (i.e. co
Read the rest
de with syntax errors). As far as I understand, that's generally why they don't use grammars. I think you might mean that a language should be designed with a concise grammar so that somebody else can reimplement it by hand more easily? That is, you want multiple independent implementations. If that's true, "context-free grammars" is the wrong term to express that notion. Context-free grammars don't handle many real languages, not just C and C++, but also Python/Perl/Ruby, and even JavaScript and Go (semi-colon insertion.) Also, a lot of tools are enabled not by grammars but by producing specific data structures for your front end. (e.g. here is the way I think about it: http://www.oilshell.org/blog/2017/02/11.html ) The different between Clang and GCC is that Clang is a library that enables a whole ecosystem of fantastic tools, including IDE support. But Clang doesn't do much at all with CFGs. The real difference is that the front end is a library that produces a very rich representation of the code. The C# front end does similar things. More links here: https://github.com/oilshell/oil/wiki/Lossless-Syntax-Tree-Pa... In other words, I would say that integrating the compiler front end into the IDE became the more popular and successful approach. And of course the compiler very much has to be designed with this use case in mind.
In So You Want to Write Your Own Language (2014)
My claim is that neither the parse tree/CST or AST is good for applications like translators. Instead I defined another term Lossless Syntax Tree, which is the data structure I want: http://www.oilshell.org/blog/2017/02/11.html I researched "production" implementations, and found that they use something like a Lossless Syntax Tree (not an AST or CST): https://github.com/oilshell/oil/wiki/Lossless-Syntax-Tree-Pa... Examples: Clang, Microsoft's Roslyn platforms, RedBaron/lib2to3 for Python, scalameta, and Go. The defining property of the LST is that it can be round-tripped back to the source. This is called out in this C# design doc, along with some conventions for associating whitespace with syntax tree nodes: https://github.com/dotnet/roslyn/wiki/Roslyn-Overview What do you think of that claim? (If you prefer not to use this deep comm
Read the rest
ent thread, feel free to contact me by e-mail instead at andychup@gmail.com.)
In ANTLR Mega Tutorial
Hi xiaq I mentioned your shell here: https://github.com/oilshell/oil/wiki/ExternalResources If there is a better summary, let me know, or feel free to edit the wiki page yourself. (I think it should be editable.) I've been in contact with the authors of the oh shell, NGS shell, and mash shell, and exchanged some interesting ideas. The design of the oil language should be more concrete in 2-3 months and I'm hoping to get feedback from others who have thought about this space. I might ping you then :) Are the elvish structured data pipelines actually separate processes, or are they goroutines? Is there a format for piping them over say SSH? I have been thinking about this a little bit for oil.
In Shell Has a Forth-Like Quality

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.