Next Generation Shell is a modern programming language for DevOps.
bash
or Python
? That's a square pegs for a round hole situation. Both are inadequate for Ops tasks. NGS aims to reduce your frustration and let you be more productive. There is no reason that you should be in this situation. (Python here represents also other general purpose programming languages).
bash does not meet any modern expectations for syntax, error handling nor has ability to work with structured data (beyond arrays and associative arrays which can not be nested). Let it go. You are not usually coding in assembly, FORTRAN, C, or C++, do you? They just don’t match the typical Ops tasks. Don’t make your life harder than it should be. Let it go. (Let’s not make it a blanket statement. Use your own judgement when to make an exception).
Python along with many other languages are general purpose programming languages which were not intended to solve specifically Ops problems. The consequence is longer and less readable scripts when dealing with files or running external programs, which are both pretty common for Ops.
See bash or Python? The Square Pegs and a Round Hole Situation blog post.
Shell user interface, the atrocity. Current shells as well as proposed alternatives treat UI as if nothing happened since the 70-s: mostly typing commands and getting some text back. Watch Unix shell - We can do better now 15 minutes video about what's wrong with the user interface and how NGS is fixing (WIP) that.
I like helping people. Reducing frustration and making people more productive just feels good. A scalable way to help is thorugh tools. That is why I created NGS. It is a programming language with typical Ops tasks in mind. See the use cases below. The next big planned part is the interactive shell.
You as the Ops person, probably wondering whether NGS would be a good fit for your tasks. NGS aims to be best fit for the use cases below.
Argv
facility for convenient building of command line argumentsdebug()
function which prints debug information, conditionally, depending on environment variable per-section settingstatus()
reporting function (previous status is overridden with new status on screen)log()
function which prints timestamped outputretry()
and stop re-implementing it hundreds of timesSee Use Cases wiki page for more information about the use cases and examples.
The language is very useful. See the the bin folder for examples. NGS is used in Beame.io for miscellaneous scripting such as testing CLI tools, performance tests orchestration, cloud manipulation, etc.
The work on the shell has just started. It is not usable yet. The shell is being implemented in NGS. See the design document.
From George Nachman, creator of iTerm2:
Neat! This is totally the project I would do if I had unlimited free time :) I've wished for something like this for a long time. I think there's a lot of room for improvement over a basic TTY, and you've nailed some of the important things
On Linux: make sure curl
and sudo
are installed
On MacOS: make sure you have brew
installed.
curl https://ngs-lang.org/install.sh | bash
ngs -pi 'sum(0..10)'
brew install ngs
sudo snap install ngs
Docker repository is at https://hub.docker.com/r/ngslang/ngs/
docker run -it --rm ngslang/ngs
Add to your Github Action the following (make sure to release the version as required)
steps:
- uses: ngs-lang/ngs@v0.2.13
After that, ngs can be used by simply calling ngs in any run step
steps:
- uses: ngs-lang/ngs@v0.2.13
- run: ngs -pi 'sum(10..100)'
To run NGS as AWS Lambda Function see https://github.com/ngs-lang/ngs-aws-lambda
Please refer to extension located in https://github.com/ngs-lang/ngs-ipython-extension
Please refer to extension located in https://github.com/ngs-lang/ngs-aws-lambda
git clone https://github.com/ngs-lang/ngs.git
# or if using git over ssh
git clone git@github.com:ngs-lang/ngs.git
cd ngs
./install.sh
sudo make install
make tests
make build
Build is currently tested with the GitHub action in .github/workflows/build.yml
and we currently test the following 64-bit architectures:
system | gcc | clang |
---|---|---|
ubuntu 20.04 | 9, 10, 11 | 9, 10, 11 |
debian 11.1 | 9, 10 | 9, 11 |
macOS 10.15 | 9, 10, 11 | 10 |
centos 7 | 9, 10, 11 | -- |
amazonlinux 2 | default (7.3) | default (11) |
fedora 34 | default (11) | default (12) |
fedora 35 | default (11) | default (13) |
archlinux | default (11.1) | default (13) |
Notes:
# If NGS is not installed (from the root of ngs project):
NGS_PATH=lib ./build/ngs SCRIPT_NAME.ngs
# If NGS is installed:
ngs SCRIPT_NAME.ngs
Tested as follows (some time ago):
If you have troubles compiling, please try to compile the commit tagged tested
.
cd build
for i in $(<install_manifest.txt);do rm "$i";done
# Debug when stuck (note to self mostly)
killall -SIGSEGV ngs
lldb --core /cores/core.XXXXX
Formula/ngs.rb
) somewhere else.ngs.rb
copy, modify:
url "https://github.com/ngs-lang/ngs/archive/v0.2.8.tar.gz"
-> url "file:///PATH/TO/ngs.tgz"
version "0.0.1-dev"
(or alike)ngs
, run tar czf ngs.tgz --exclude=build ngs
brew install -d -s ./ngs.rb
(wherever the ngs.rb
is)# Build the docker
docker build -t ngs .
# Run the container
docker run -it --rm ngs
# Use NGS inside the container
ngs -pi 'sum(0..10)'
On Linux
# --- Linux ---
cd doc
rm -r out
mkdir out
./make.ngs out
On Mac, follow the instructions to create case sensitive volume.
# --- Mac --- One time setup ---
cd doc/
ln -s /Volumes/YOUR-VOLUME-NAME out
# --- Mac --- Each time ---
cd doc/
rm -r out/*;
./make.ngs out
a = [1, 2, 3]
arr = a.map(X*2) # arr is now [2, 4, 6]
for i in arr {
echo(i)
}
h = {"a": 1, "b1": 2, "b2": 3}
echo(h.filterk(/^b/).mapv(X+10)) # {b1=12, b2=13}
F my_func(x:Int) x*10 # Single expression does not require { ... } syntax
doc This method is documented!
F my_func(s:Str) {
t = s * 2
"[" + t + "]" # Last value returned as the result
}
echo(my_func(1)) # 10
echo(my_func("xyz")) # [xyzxyz]
echo(my_func) # <MultiMethod with 2 method(s)>
More information about the language and syntax in particular is in ngslang.1
NGS has AWS library based on concept of Declarative Primitives
TLDR:
This is how an instance can be created using NGS (real working code).
{
NGS_BUILD_CIDR = '192.168.120.0/24'
NGS_BUILD_TAGS = {'Name': 'ngs-build'}
vpc = AWS::Vpc(NGS_BUILD_TAGS).converge(CidrBlock=NGS_BUILD_CIDR, Tags=NGS_BUILD_TAGS)
gw = AWS::Igw(Attachments=[{'VpcId': vpc}]).converge(Tags=NGS_BUILD_TAGS)
rtb = AWS::RouteTable(VpcId=vpc).converge(Routes=Present({"DestinationCidrBlock": "0.0.0.0/0", "GatewayId": gw}))
subnet = AWS::Subnet(VpcId=vpc, CidrBlock=NGS_BUILD_CIDR).converge()
sg = AWS::SecGroup("ngs-build-sg", vpc).converge(
Description = "ngs-build-sg"
Tags = NGS_BUILD_TAGS
IpPermissions = [ AWS::util::world_open_port(22) ]
)
ami = AWS::Image(OwnerId=AWS::AMI_OWNER_DEBIAN, Name=Pfx('debian-jessie-amd64-hvm'), RootDeviceType='ebs', VolumeType='gp2').latest()
instance = AWS::Instance(
ImageId = ami
State = null
KeyName = ENV.get('AWS_NGS_BUILD_KEY', 'ngs-build')
SecurityGroups = sg
SubnetId = subnet
PublicIpAddress = true
Tags = NGS_BUILD_TAGS
).converge(
State = 'running'
)
# Get SSH fingerprint from machine's console
AWS::add_to_known_hosts(instance, 'PublicIpAddress')
}
stdlib
's Table
to do output layout and columns configuration. Table
handles columns presence and order and it can be configured via environment variable.env-role
or env-role-N
, depending on whether you have one or more machines of specific role in the environment.CHANGELOG.md
dev
branch).If the change is big or involves modifying the syntax, it's better to coordinate with Ilya before you start.
( This section is moving to Wiki and Issues )
See "feature" issues and wiki: https://github.com/ngs-lang/ngs/issues?q=is%3Aissue+is%3Aopen+label%3Afeature
You are welcome to open new issues with feature-request
label if there is something you would like to see in NGS.
ls $a
, when the cursor is on $a
)curl URL
-> curl has argument of type URL.
curl [SHORTCUT_KEY_PRESSES]
->
menu with object types -> remember the selection.ec2kill
< ec2din ...
.Following instructions should work (tested on Debian)
cd small-poc
mkdir ssl
cd ssl
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout mysitename.key -out mysitename.crt
cd ..
npm install
nodejs server.js
ls
pr
- a long process with progress barsleep
- a process that sleeps for 5 secondsfail
- a process that failsAll of the shells below
AwsElb(...)
function call will make sure the load balancer exists and is configured as described. NGS has work-in-progress AWS library. It's already usable for a subset of AWS resource types.oil shell is a very promising project with motivation similar to that behind NGS. It's too early to tell the differences.
fish shell has very nice features and improvements but is still more bash-like. For example it doesn't have nested data structures nor a full-featured programming language.
Plumbum makes it easier to call shell commands from python. Too verbose to be used as a shell or shell script. It helps when you need to use python and call external programs. Primary target audience seems to be Python developers, not system engineers.
Xonsh Python with bash-like additions. Python is not a domain specific language, making bash-like additions can not bring it to be optimal for system tasks.
rc shell is much closer to Bash than to NGS.
Es: A shell with higher-order functions . ES and NGS share quite a bit of common ideas. NGS goes further with making a shell a real programming language. ES vs NGS would probably be a matter of personal preference. ES is simpler and been here for a while.
elvish features nestable data structures, lambdas and namespacing and is pretty close to general purpose programming language when it comes to the semantics. When compared to NGS, it prefers to extend traditional mechanisms like output capture and pipelines as more expressive programming constructs, and looks a bit more like traditional shells (it is non-POSIX though). It is currently terminal-oriented.
while ...;do ... done
, hence joins
and splits
functions which avoid name clashing.mydata.map(myfunc)
.false
for example must return 1 and it's not an exception in NGS. test -f ...
that returns 0 or 1 is fine, 2 is syntax error which is converted to exception. See blog post about NGS exit code handling.Windows PowerShell is probably the best thing that ever happened to Windows. I'm not familiar with it enough but here are my points
$
in front of variables come to mind.Shill - Scripting with Least Privilege . Security focused (capability-based), runs on FreeBSD only (looks like Shill kernel module is required), examples mostly show security features, written in Racket. Not much development since initial commit at 2014. Real world usability is unclear. At this point I assume NGS as a programming language is much more usable.
val resp = Http("https://api.github.com/repos/scala/scala").asString
and val parsed = upickle.json.read(resp.body).asInstanceOf[upickle.Js.Obj]
. In NGS that would be parsed=``curl -s "https://api.github.com/repos/scala/scala"``
. On the other hand Ammonite-Ops and Ammonite-Shell aim to make common "operations" tasks convenient to handle.sh module for Python: "sh is a full-fledged subprocess replacement for Python 2.6 - 3.5, PyPy and PyPy3 that allows you to call any program as if it were a function".
sh.wc(sh.ls("-1"), "-l")
is really not the same as ls -1 | wc -l
. BTW, -1
is not needed because ls
does that automatically when when stdout
is not a tty
(try ls | cat
).p = sh.find("-name", "sh.py", _bg=True)
is not the same as p = $(find -name sh.py &)
(NGS)ls >/tmp/dir_contents
(bash, NGS) becomes with open("/tmp/dir_contents", "w") as h: sh.ls(_out=h)
in sh.Rash: The Reckless Racket Shell
Racket is a general-purpose programming language as well as the world’s first ecosystem for language-oriented programming. Make your dream language, or use one of the dozens already available, including these ...
Shell++ is a programming language that aims bring features from modern languages, as facility to manipulate data structures, object oriented programming, functional programming and others, to shell script.
I wanted a language that runs shell commands like Bash, and manipulate data structure with the ease of Python
MAKE MY LIFE EASIER AND ONLY THAT
Nu Shell - compared on 2020-02-01, Nu Shell commit dcdfa2a866bbf1e5737d9f77a3ef5ba971b10083