Zx is good if JavaScript is only language you know. If you have ability to program or learn other programming languages, Python with packages like Shell and Plumbum might be better choices for shell scripting tasks that outgrow shell.
- Python code with Shell is easier to read ana write
- No nees to carry async/await keywords thru the code
That's fair. My Latin is non-existent, and I clearly was too eager to look at example source instead of reading the description. I'll take my criticism and walk away.
Maybe, but the main advantage of `zx` (at least for me) is that I don't have to manage another language environment. I can keep everything contained within Node :)
The problem is Node, especially all the packages that you’ll end up using under the hood, it’s seems quite risky especially if you don’t have super tight control over your Node SBOM.
Would be a bit more interesting to me if it was a JS shell built from the ground up without the entire mess of the Node package dependency baggage.
While I agree that Node's ecosystem is not the best, it's what we have in the frontend world.
If you're working on a Node-based service or React app, you already have to deal with Node and its package ecosystem. Adding a couple of extra MB (or even KB, depending on package reuse) on top of your existing chain of dependencies is a tiny con to the huge benefit of not having to do logic in Bash :)
The problem is that you don’t always know what is actually being executed, shell scripting is risky as it is without the rabbit hole that is the Node dependencies system.
Yes. I started programming in JavaScript in 1999 and Python in 2003, so it is my subjective opinion based on mastering the both languages. There are some factual and objevtive features making Python syntax more friendly, but it is a worth of a blog post to explore. And in the end there is no point, as JavaScript maximalists would not care.
Maybe but Python is sloooow and its type annotation situation is pretty poor.
I would recommend using Deno. It has the following advantages:
* Uses Typescript which gives you a great static typing system.
* Runs via V8 so it's about a million times faster than Python.
* Single statically linked binary with no project setup files required (package.json/dependencies.txt) makes it about a million times easier to deploy than either Node or Python. Especially on Windows.
* You can still use third party libraries even without a project file and you get IDE integration.
It's the clear winner at this point. Someone has even made a version of zx for it:
Python interpreter by itself is fast, it spawns in a few milliseconds, but it can slow to a crawl if you need libraries, and easily take a few seconds.
Startup time is very slow. I just tested on my system and cold startup was 1 second (!) and hot 180ms. Vs 80ms and 64ms for Node.
Also it obviously depends what your CLI tool is doing. Just because something is a CLI tool doesn't mean it doesn't do much stuff and therefore performance doesn't matter.
For example Scons is a CLI tool. It's a build system written in Python. Everybody abandoned it because it was dog slow.
Mercurial is a CLI tool. It's a VCS written in Python. Most people have abandoned it partly because it is slow (and partly because Github exists).
You can read about Mercurial's troubles with Python performance here:
> Performance is a significant pain point with Python. There are multiple facets to the performance problem:
> * Startup overhead
> * General performance overhead compared to native code
> * GIL interfering with parallel execution
> It takes several dozen milliseconds to start a Python interpreter and load the Mercurial Python modules. If you have many extensions loaded, it could take well over 100ms just to effectively get to a Mercurial command's main function. Reports of over 250ms are known. While the command itself may complete in mere milliseconds, Python overhead has already made hg seem non-instantaneous to end-users.
It is definitely noticeable even when you run a command once. But it really becomes a problem when your command is run lots of times as part of some other system.
For example if you're using Python to process a lot of files via Make (something my work's build system does unfortunately) then it can end up costing 10s of seconds which is kind of insane.
That doesn't quote/escape arguments and with zx you can do the shebang so you don't need the import but implementing that in deno shouldn't be too hard I think.
Which makes no sense if the developers are the users...
But in the spirit of "there are only two business models - bundling and unbundling", I guess there are only two marketing tricks: use an old term for a new thing, and introduce a new term for an old thing...
Or more charitably, while the UX/DX distinction isn't very meaningful for this project, there are lots of products (e.g., payments) that target both (non-developer) end users and developers. It helps to be able to separate the personas.
I don't think this holds. As the rule goes, there are only three cardinal numbers: zero, one, many. What are the chances you product has only two meaningful personas - "users" and "developers"?
Take that payment system. People who buy things are obviously users, people who write CMS plugins for that system are obviously developers. But what about, say, analysts studying reports from that system? Accountants making sure the money flows where it should? Sysadmins keeping the backend components running? These are all users too.
Where UX makes sense as a broad concept, giving a separate acronym to one small subset of potential users... doesn't make sense.
I feel like the await keyword everywhere is a bit verbose. One might use something like the gpp preprocessor (hopefully the macros could be defined in a separate file):
I am not talking about JavaScript in general. I have been doing mainly JavaScript programming for the last 8 or 9 years or so (before that other languages like C# and C++ for many years). And I use those keywords all the time.
For this specific use case, they are trying to replace shell scripts. So I thought maybe some people might be willing to consider abbreviations for the async and await keywords for this case.
Not sure what this comment means. Javascript has no "async-by-default" model.
The author of this library has chosen to make the "$" function they provide async; this isn't a JS design feature or limitation, it's just the lib author's choice.
Requiring it for every command by default sucks, but on the other hand, the ability to easily make scripts async is a huge benefit.
I've seen so many cases of processes being synchronous simply because doing it differently would require an unrealistic amount of custom parallelism code.
I think the idea is that the majority of the script will be written in pure JS, with only occasional calls out to subprocesses, so “every command” is far from every line.
You frequently see the same mental mismatch when shell-scripters try to use Python, and complain how hard it is to pipe with POpen, instead of using the built in string processing features.
What I don’t like about backticks in Ruby is that they “ignore” errors in commands you run. It’s up to the program author to remember to check $? for the last executed command’s exit status. And guess how many times the average Ruby script using this feature implements error handling? Usually it’s totally forgotten.
To be safe, abstractions that make it easy to shell out must also:
- escape all variable interpolations by default using “shellwords” or similar.
- throw exceptions on error by default.
Backticks in Ruby are very easy to use, but aren’t safe.
I agree that people often don't treat the exit code the way they should when using the backticks. However there's better options in the ruby stdlib too, like `system` and `spawn` and `popen`. Using the other methods allows you to also sidestep the shell if you know the arguments you want to pass.
In that case, welcome to Next Generation Shell (I'm the author), which actually cares about errors when running external programs. Yes, I mean much more than naive "non-zero is error" because that's just not true in many cases.
I'm having a hard time believing that Google uses this much internally. Is github.com/google just a place where Googlers can put personal projects to get additional exposure?
The copyright of the thing Googlers build on their oswn time are usually owned by Google and so it ends up on the Google org if they want it on GitHub. They usually have a disclaimer like "this is not a official Google product..."
This isn't correct: if a Googler writes some code from scratch, which is unrelated to their work, on their personal time, and using their personal laptop... then it's definitely not owned by Google.
There could be gray areas where code ownership could be disputed, but in general your employer owns only the intellectual property it paid for.
"The provisions of this Agreement requiring disclosure and assignment of Inventions to Google do not apply to any invention that I have developed entirely on my own time without using any of Google Property (as defined below) or Google Confidential Information, except for those inventions that either (i) relate at the time of conception or reduction to practice of the invention to Google’s business, or actual or demonstrably anticipated research or development of Google or (ii) result from any work or services that I performed for Google."
> (i) relate at the time of conception or reduction to practice of the invention to Google’s business, or actual or demonstrably anticipated research or development of Google
That's the catch. Not related to what _you_ do at Google, but related to _anything_ that Google does. Pretty much all the stuff I wanted to work on in my spare time while employed at Google could be seen as related to Google's business/research, as Google does a lot of things. And that's how Google seems to read this too, considering how the Open Sourcing documentation [1] is written.
[1] - https://web.archive.org/web/20210710210932/https://opensourc... “As part of your employment agreement, Google most likely owns intellectual property (IP) you create while at the company. Because Google’s business interests are so wide and varied, this likely applies to any personal project you have. That includes new development on personal projects you created prior to employment at Google.”
Not true. You need explicit permission (there is a process for obtaining it, and it is very lightweight as I've done it myself). The general idea is that you get permission without much hassle if you develop something that doesn't compete with Google. You need to argue your case otherwise.
Source: I'm a Googler that went through the process before.
Edit #1
for all Googlers reading this: search "IARC" internally and you should land on the proper page to kickstart the process.
Many companies make claims over their employees' intellectual property. How much of a claim they actually have legally is a different question, which depends on the country (and sometimes state) where the employee works, and companies routinely attempt to claim more than they legally can.
Maybe true, but I am unwilling to try my luck. I mean, the process I mentioned above takes 30 minutes [1] if it's clear you aren't competing with Google and so I don't see a major issue about playing it safe and have written consent to develop your idea/project.
[1] you fill a form with the general idea description, you explain succinctly why it doesn't compete to any Google product, and you acknowledge you won't use Google time and resources to develop it. Then a committee reviews it and in ~1 week you get your approval or request for more details.
It takes maybe 30 minutes to fill out, but the O(days) approval latency is what absolutely killed me. No way to do impromptu commits to random non-Google-license-approved projects, no way to hack together something with friends over a beer, no way to quickly bash together a proof of concept and release it the same evening.
It might work for people who chisel away at their own long-term one-person pet projects, but breaks down if you're used to quickly hacking away collaboratively in various groups. Especially if you're an active member of a hackerspace.
Many countries have a "formula" (legal definition) for a "contract", which include fair exchange of something for something else, e.g. time and labor for money. If Google forces their developers to work for free (labor for nothing), then it fails to meet legal definition of the contract.
IMHO, such "forced labor for free" is a form of slavery. Slavery is forbidden by law.
If a developer want to publish his project under Google brand, then exchange may be considered as fair (project code for Google branding).
The IARC process is only necessary when Google might own copyright in the first place (those gray areas I mentioned earlier).
I went through the IARC process 2 years ago for a startup I was about to found in Tokyo, and obtaining clearance was easy, as you say. It's an extra precaution to avoid future litigation, but not legally required if you keep your personal coding activity clearly and provably separate from your work activity.
There is very little code that a Googler could write that is unrelated to their employer’s business. You’re almost certainly going to need an explicit carve-out, as other Googlers in the thread have pointed out.
Double-check your employment contract. The offer I received (and declined, primarily for other reasons but this was on the list) in 2017 clearly stated that it had to be unrelated to any of Google's work as a whole, and in fact to Google's actual or anticipated work - not just to the employee's assigned work.
Often they are not entirely personal in that they wrote the code using 20% time (so this is code paid for by Google) and use them as part of their job and/or make them available to other users internally. So Zx might be used inside Google somewhere.
Since they started out owned by Google, you need permission to open source them.
But how much company support they have and how popular they are varies.
Yup - or at least that’s what Google tells their employees. Want to publish something - you’d better get permission, and stick the Google name on it. And based on my limited understanding of the US contracts, is also true in practice.
There are some exceptions depending on local laws and contracts though, so it’s only mostly and not always true.
I was under the impression that `github.com/google` was largely projects being worked on by googlers where the code is owned by google, but the code isn't always being used by google. Say 20% time work, side projects built using google resources, etc.
In my first job I gave a try at using Python for scripts.
It was a terrible idea, as I now had 3 problems instead of 1:
1 - Writing scripts, plus:
2 - Installing Python in every host that needed to run those scripts
3 - Maintaining Python and the necessary dependencies up to date in each host / container.
(2) and (3) are trivial when done just once in your own computer, but end up being a huge time sink for larger heterogeneous environments with (possibly) network and security barriers. Moreover, if you are using containers, installing Python will make images unecessarily large.
Granted, I'm not a JS person, but I imagine one will have the same issues.
Even though bash has its shortcomings, I really appreciate how low maintenance it is as long as you keep scripts small and sane.
That's why Perl is my go-to choice for glue scripts. It's almost always installed by default, it has stayed consistent for decades without any breaking changes, its regex support is by far the best around, and its almost as good as the shell at gluing commands together.
It's also unlikely you have Python installed on Windows though, and there's a non-insignificant change that's an old or random version (probably even Python 2). You can't rely on anything on Windows, so you're definitely going to also install a runtime from Chocolatey or similar.
> That's why Perl is my go-to choice for glue scripts. It's almost always installed by default
My first thought was related to this as well: Perl is _always_ installed, and based on Python's popularity (compared to Perl, at least), I'd assume that Python also was installed by default?
That's an honest question, btw: I use Perl quite a lot, Python not so much (at all). :)
I've seen instances of some Unix systems not having Perl installed, but that's very rare. Basically everything directly or indirectly depends on Perl, so you really have to run your scripts on a minimal install of RHEL of FreeBSD with 0 ports in order to get into such a situation.
Most container base images are often so barebone you can't really count on them containing anything. For instance, on an Alpine image you can't count on bash.
JS is marginally better than Python for this, because tools for runtime and package version management are better for Node than for Python (proper lockfiles, local package folders, npm bundled with Node for installation, etc.).
Still, zx isn't as nice as Ruby, which has backticks for calling shell as part of the language. So, you don't have to have a separate package installed, just the ruby runtine.
But Perl is even better! Just like Ruby, it comes with backtick shell execution build-in, but unlike Ruby Perl is ubiquitous and is pretty strict about backward compatibility. So, your scripts will just run on all machines you have, no matter what distro you use and how old the machine is (within reason).
Zx seems[1] to take advantage of the way template literals work in JS to do proper shell escaping of the parameters to prevent command injection. Is that handled by the Ruby and Perl backtick syntax as well?
Luckily today you can side step many of these issues. You can compile a copy of python + modules + pex into a single file with some open source tooling and get a flat file you just need to copy to your hosts.
Bash just sort happened to be the lowest common denominator in most unix style environments. Because it just sorta ended up being the default. Unix ended up being this different thing where each distro seems to be kind of unique. Then on top of that they are very easy to customize. So while one distro you can assume a particular python level the next disto python is totally optional. Mix in containers and docker images and you have a new level of 'what may or may not be there'. Ah but you may say 'oh just use tech XYZ' that may or may not have the exact same issue as using python in its place. So either 'deal with it' and install what is needed and keep it up to date. Or 'play the LCD game' you use only the bare min and hope you can build something useful enough in bash when another lang may be more appropriate.
This is a bit of a Linux specific view of the universe. Yes posix has a standard for how sh should work. But there were specific implementations of sh, and you would get those on commercial Unix or *BSD.
Later shells came in and filled some gaps. OpenBSD still has ksh by default. Linux distros had bash as their /bin/sh.
After reading about various vulnerabilities which are the direct result of backwards JS language features - most recently prototype pollution - I’d be hesitant to use JS for writing scripts.
The node ecosystem is built around having third-party dependencies for everything, which makes it impossible to meaningfully vet the code you're running, and once a dependency gets hijacked, all its dependencies are screwed too.
I suppose it's easy to poke fun at combining the "best" of shell scripting and JS. But, the examples of using await() with child processes and pipes are pretty nice, and less verbose than the Perl or Python equivalents. It does seem well designed for anything where you're orchestrating parallel runs of commands.
For Perl, there is now Future::AsyncAwait.[0] Mojolicius has already adopted it, so things are moving forward at the speed of the magnetic poles shift. :)
Plus while Mojolicious' support for running external processes is extremely limited because it's not really a goal of the project, http://p3rl.org/IO::Async::Process (by the author of the async/await system) is a gloriously complete interface and you can run Mojo::IOLoop and IO::Async::Loop code in the same process just fine.
As annoying as having to write "await" in front of everything is (probably should have a variant of $ that's synchronous), the ability to effortlessly implement parallelism is something that all other common scripting (and many "full") languages seem to lack.
Even Go, that prides itself on the good support for parallelism, fails once you actually want go get results back.
If this were paired with some way to also display the status/output of multiple commands in parallel, this would be the ultimate toolkit to write scripts.
If you look at apt, for example: Does it really have to wait for the last package to be downloaded before installing the first? Is there a good reason, on modern SSD-based computers, to not parallelize the installation of multiple packages that don't depend on each other?
You lose the ability to know whether they succeeded or failed, though. Like most things given to you for free by the shell in shell scripting, it's only like halfway to a real solution.
(If you know how many subshells you started and won't get confused by which is which, you can use `wait -n && wait -n && ...` in bash)
> Even Go, that prides itself on the good support for parallelism, fails once you actually want go get results back.
It's doable if you're willing to build a very thin abstraction over whatever you're trying to parallelize keeping in mind all possible edgecases [1] and how you'd like to handle them.
A generic `run N things in parallel and collect their results` function would be nice, but would probably end up being quite unwieldy in comparison to just writing out a purpose-specific function for what you exactly need.
[1] - Error handling, timeouts/cancellation, maximum amount of processes running in parallel, wait-for-full-join vs. returning results as they appear, introspection of currently running subordinates, subordinate output streaming/buffering/logging, ... A lot of things to consider when you're trying to build something universal, but that are easy to solve/ignore when you're building something purpose-specific with known constraints.
That's the thing though... if the options are "write and test 30 lines of custom parallelism code to handle this stuff" or "everyone waits twice as long for their results", in practice most developers choose the latter.
Imagine if instead of that, you could do:
foo, bar, []err := await getFoo(), getBar()
if len(err) > 0 {
return nil, nil, fmt.Errorf("Frobnication failed: %s", err)
}
return foo, bar, nil
Of course, JavaScript having exceptions as the main error-raising approach and `await` supporting them makes that a lot easier.
First impression is that I wouldn't go near it until it settles down a bit — it was on v1.7 in May and now on version 3 already.
Great that it's under active development, but changes to my scripts are infrequent and slow. I wouldn't want to be touching an old script on a server somewhere saying "How do I do X in ZX again?" and everything I find online is now for v15 while I'm still on v3.
Maybe if it had plans around a LTS version I'd take a look at that stage.
To be honest though I like doing things in bash. You can get pretty far & it's 100% portable. If something's too complicated for bash it's probably time it's not just a simple CLI script anymore, in my experience.
The major version bumps imply breaking changes. Two major versions within a few months implies I might have to refactor my code every couple of months to stay up to date, or face a buildup of tech debt if I want to take advantage of a new feature in the future.
If there are no breaking changes, then I would feel better if they called it v1.9.
If you wrote your script against v1.7 and now they're on v3, you can still run your script. The v1.7 source and binary haven't disappeared. It's still available and work exactly the same as when you wrote your script.
I haven't looked into Zx yet, but at least for JavaScript that "what color is your function" article also applied before they added the syntactic sugar. If your function was async via a direct callback then the calling function would have to accept a callback too.
Those are small examples but for more complex scripts I expect you'd mostly have synchronous code, for example to process strings, validate input, etc. and the "await" will become the exception rather than the norm.
Given Promises and callbacks have always been pervasive in JS—that it’s always been heavily asynchronous—I can’t imagine thinking async/await was a mistake. It’s a drastic ergonomic improvement over both, and it also drastically improves debugging and error stacks.
Adding it to a language where IO is typically blocking with other ergonomic concurrency mechanisms, that I can imagine being somewhat controversial.
It would be good if async weren’t infectious, but as a sibling comment said that was already the case with Promises and callbacks.
It would maybe also be better if concurrency was the default behavior and keeping a reference to a promise was the explicit syntax, but I could see downsides to that. It potentially hides/encourages excessive use of expensive calls. And implicit concurrency is a potential source of many bugs.
Template tag functions in JS can intercept the interpolation values passed in. So it's possible they're automatically escaping to prevent shell injection.
They could also be parsing out the first word as the command and not using shell execution at all.
That example is immediately followed by two sentences of text, of which the second sentence is:
> The zx package provides useful wrappers around child_process, escapes arguments and gives sensible defaults.
lit-html and at least one SQL generating package I've seen use the template string custom interpolation mechanism to auto-escape things - it's a pretty established pattern at this point in javascript land ... but also, yes, until you learn that, it totally does look prone to injection. I've got in the habit of going and finding the template string interpolation function and double checking, because otherwise I find it hard to convince my brain to believe it isn't prone to injection and it interferes with my skim reading the code ;)
I know a bit of bash, but I'm always looking up how to do things I know are simple in JS. I would love to be able to write scripts in JS because I'm faster with it, and I find it easier to read.
What is the nature of your outrage exactly? Bash is very difficult as a language to write code in. JS is very familiar to a lot of developers and its syntax is orders of magnitude easier to understand than Bash.
The prejudice against JS developers is that they are seen as low class janitorial code monkeys by ‘real programmers’. It hurts these people even more because the language just succeeds and succeeds despite all the hate.
I would say that it's more that Bash is good at something and JavaScript is good at other things and just because they are technically scripting languages doesn't mean that they are naturally a good fit in each other's domains. The README's comment tends to point towards an idea that all languages that can write scripts are equally interchangeable and of all choices JavaScript is the perfect choice. To people that are working on a variety of scripts in numerous languages who all have individual advantages and disadvantages, it comes off as nonsense.
I think definitely there are better alternatives to JS in command line world like python but if someone decided to use something other than bash as a programming language that’s a win in my book. It has its place for basic scripts and general command line trickery but anything beyond that is using a hammer to do brain surgery.
yeah same. As a front-end webdev who writes JS frequently, I've _never_ written shell scripts and thought "Wow, I'd really rather use JavaScript for this"!
Not saying it doesn't happen, just that it hasn't been my experience.
You’ve never written a bash script and needed to parse, format, concat lots of strings? What about arrays of strings? All of which is easier in just about any modern language.
As a front-end dev who works with JS all the time and never writes shell scripts, every time I have to deal with shell scripts I think "I'd really rather use JS for this".
I am also a frontend dev. My experience has been completely opposite from yours. Node.js is my go-to tool for writing automation scripts.
I think these are some reasons why our mileages differ:
- I need my scripts to work in both Windows and Linux.
- I am not very experienced with bash or other shell.
- Most of my "automation work" only involves reading text from a file, transform it, and write to another file. (Generating SQL commands, doing stats about town names, etc.)
No, this is an untagged template literal[1], which just generates a string. The other ones are tagged, which means that the template string and the parameters are (separately) passed to the $ function.
This looks horrible to me. The mixing of bash commands in Javascript looks absolutely terrible and running node itself for scripting is a total mess(node_modules, versions).
I usually go with bash + set -euxo pipefail and if it becomes too complicated I switch to Python.
GoLang/Rust are the perfect tool when distributing tools as a single binare. Where in the world does JS fit in?
168 comments
[ 3.7 ms ] story [ 232 ms ] thread- Python code with Shell is easier to read ana write
- No nees to carry async/await keywords thru the code
- Powerful plain text manipulation in the stdlib
https://pypi.org/project/python-shell/
https://plumbum.readthedocs.io/en/latest/
> Plumbum (Latin for lead, which was used to create pipes back in the day)
Personally, I only see it as the old name for lead. Interesting to see how others are wired.
Not sure how I feel about needing Node.JS to run shell scripts…
Would be a bit more interesting to me if it was a JS shell built from the ground up without the entire mess of the Node package dependency baggage.
If you're working on a Node-based service or React app, you already have to deal with Node and its package ecosystem. Adding a couple of extra MB (or even KB, depending on package reuse) on top of your existing chain of dependencies is a tiny con to the huge benefit of not having to do logic in Bash :)
If you are fluent in Node, it should be easy to avoid further dependencies.
0: https://arve0.github.io/npm-download-size/#zx
That is pretty subjective
I would recommend using Deno. It has the following advantages:
* Uses Typescript which gives you a great static typing system.
* Runs via V8 so it's about a million times faster than Python.
* Single statically linked binary with no project setup files required (package.json/dependencies.txt) makes it about a million times easier to deploy than either Node or Python. Especially on Windows.
* You can still use third party libraries even without a project file and you get IDE integration.
It's the clear winner at this point. Someone has even made a version of zx for it:
https://deno.land/x/zx_deno@1.2.2
However, situation is similar with nodejs.
Also it obviously depends what your CLI tool is doing. Just because something is a CLI tool doesn't mean it doesn't do much stuff and therefore performance doesn't matter.
For example Scons is a CLI tool. It's a build system written in Python. Everybody abandoned it because it was dog slow.
Mercurial is a CLI tool. It's a VCS written in Python. Most people have abandoned it partly because it is slow (and partly because Github exists).
You can read about Mercurial's troubles with Python performance here:
https://www.mercurial-scm.org/wiki/OxidationPlan
> Performance is a significant pain point with Python. There are multiple facets to the performance problem:
> * Startup overhead
> * General performance overhead compared to native code
> * GIL interfering with parallel execution
> It takes several dozen milliseconds to start a Python interpreter and load the Mercurial Python modules. If you have many extensions loaded, it could take well over 100ms just to effectively get to a Mercurial command's main function. Reports of over 250ms are known. While the command itself may complete in mere milliseconds, Python overhead has already made hg seem non-instantaneous to end-users.
For example if you're using Python to process a lot of files via Make (something my work's build system does unfortunately) then it can end up costing 10s of seconds which is kind of insane.
[0] -- https://github.com/xonsh/xonsh
https://gist.github.com/zandaqo/93004fb265146a95aadb28ec851a...
Here is a more full fleded version.
But in the spirit of "there are only two business models - bundling and unbundling", I guess there are only two marketing tricks: use an old term for a new thing, and introduce a new term for an old thing...
Take that payment system. People who buy things are obviously users, people who write CMS plugins for that system are obviously developers. But what about, say, analysts studying reports from that system? Accountants making sure the money flows where it should? Sysadmins keeping the backend components running? These are all users too.
Where UX makes sense as a broad concept, giving a separate acronym to one small subset of potential users... doesn't make sense.
For this specific use case, they are trying to replace shell scripts. So I thought maybe some people might be willing to consider abbreviations for the async and await keywords for this case.
The author of this library has chosen to make the "$" function they provide async; this isn't a JS design feature or limitation, it's just the lib author's choice.
Although this would be fighting the language...
I've seen so many cases of processes being synchronous simply because doing it differently would require an unrealistic amount of custom parallelism code.
You frequently see the same mental mismatch when shell-scripters try to use Python, and complain how hard it is to pipe with POpen, instead of using the built in string processing features.
It doesn't matter where input comes from. Input needs to be escaped for the context it's used in, period. Non-exploitable doesn't mean it's correct.
To be safe, abstractions that make it easy to shell out must also:
- escape all variable interpolations by default using “shellwords” or similar.
- throw exceptions on error by default.
Backticks in Ruby are very easy to use, but aren’t safe.
https://ilya-sher.org/2017/01/28/ngs-unique-features-exit-co...
There could be gray areas where code ownership could be disputed, but in general your employer owns only the intellectual property it paid for.
Source: I'm a Googler (until next month).
Not in the “haha, yes of course”, in the “I’ve spoken to HR and have it writing” kind of way.
I’ve heard this is not true from others, it is simply true in certain geographical regions where local laws override the contract you signed.
That's the catch. Not related to what _you_ do at Google, but related to _anything_ that Google does. Pretty much all the stuff I wanted to work on in my spare time while employed at Google could be seen as related to Google's business/research, as Google does a lot of things. And that's how Google seems to read this too, considering how the Open Sourcing documentation [1] is written.
[1] - https://web.archive.org/web/20210710210932/https://opensourc... “As part of your employment agreement, Google most likely owns intellectual property (IP) you create while at the company. Because Google’s business interests are so wide and varied, this likely applies to any personal project you have. That includes new development on personal projects you created prior to employment at Google.”
Source: I'm a Googler that went through the process before.
Edit #1 for all Googlers reading this: search "IARC" internally and you should land on the proper page to kickstart the process.
https://opensource.google/docs/releasing/
Compare e.g. https://thebusinessprofessor.com/en_US/property-law/californ...
I bet Google lacks the copyright for many of the projects they claim.
Good luck taking Google to court.
[1] you fill a form with the general idea description, you explain succinctly why it doesn't compete to any Google product, and you acknowledge you won't use Google time and resources to develop it. Then a committee reviews it and in ~1 week you get your approval or request for more details.
It might work for people who chisel away at their own long-term one-person pet projects, but breaks down if you're used to quickly hacking away collaboratively in various groups. Especially if you're an active member of a hackerspace.
IMHO, such "forced labor for free" is a form of slavery. Slavery is forbidden by law.
If a developer want to publish his project under Google brand, then exchange may be considered as fair (project code for Google branding).
I went through the IARC process 2 years ago for a startup I was about to found in Tokyo, and obtaining clearance was easy, as you say. It's an extra precaution to avoid future litigation, but not legally required if you keep your personal coding activity clearly and provably separate from your work activity.
In some locations, employers can’t claim copyright on works unrelated to your current role.
(Obviously this is not legal advice, talk to your own layers, etc.)
Since they started out owned by Google, you need permission to open source them.
But how much company support they have and how popular they are varies.
There are some exceptions depending on local laws and contracts though, so it’s only mostly and not always true.
It was a terrible idea, as I now had 3 problems instead of 1:
1 - Writing scripts, plus:
2 - Installing Python in every host that needed to run those scripts
3 - Maintaining Python and the necessary dependencies up to date in each host / container.
(2) and (3) are trivial when done just once in your own computer, but end up being a huge time sink for larger heterogeneous environments with (possibly) network and security barriers. Moreover, if you are using containers, installing Python will make images unecessarily large.
Granted, I'm not a JS person, but I imagine one will have the same issues.
Even though bash has its shortcomings, I really appreciate how low maintenance it is as long as you keep scripts small and sane.
My first thought was related to this as well: Perl is _always_ installed, and based on Python's popularity (compared to Perl, at least), I'd assume that Python also was installed by default?
That's an honest question, btw: I use Perl quite a lot, Python not so much (at all). :)
Plus of course if you want to use (pure perl) cpan dependencies I wrote http://p3rl.org/App::FatPacker and http://p3rl.org/Object::Remote to make that easier.
Why do you link to p3rl.org? And, more importantly, why do you link to something that doesn't exist?
For servers it's less common, but enterprise systems never cease to amuse me.
Still, zx isn't as nice as Ruby, which has backticks for calling shell as part of the language. So, you don't have to have a separate package installed, just the ruby runtine.
But Perl is even better! Just like Ruby, it comes with backtick shell execution build-in, but unlike Ruby Perl is ubiquitous and is pretty strict about backward compatibility. So, your scripts will just run on all machines you have, no matter what distro you use and how old the machine is (within reason).
[1] https://github.com/google/zx/blob/3.0.0/test.mjs#L30-L33
Most images will either have bash or ash installed. ash, being lightweight, is the choice of alpine and related distros.
Later shells came in and filled some gaps. OpenBSD still has ksh by default. Linux distros had bash as their /bin/sh.
Maybe I’m just being paranoid.
The node ecosystem is built around having third-party dependencies for everything, which makes it impossible to meaningfully vet the code you're running, and once a dependency gets hijacked, all its dependencies are screwed too.
> Will Windows be supported?
> There are no plans to support Windows.
[0] https://metacpan.org/pod/Future::AsyncAwait
Even Go, that prides itself on the good support for parallelism, fails once you actually want go get results back.
If this were paired with some way to also display the status/output of multiple commands in parallel, this would be the ultimate toolkit to write scripts.
If you look at apt, for example: Does it really have to wait for the last package to be downloaded before installing the first? Is there a good reason, on modern SSD-based computers, to not parallelize the installation of multiple packages that don't depend on each other?
Still doesn't let you easily get the output of the two commands, but a good start.
(If you know how many subshells you started and won't get confused by which is which, you can use `wait -n && wait -n && ...` in bash)
It's doable if you're willing to build a very thin abstraction over whatever you're trying to parallelize keeping in mind all possible edgecases [1] and how you'd like to handle them.
A generic `run N things in parallel and collect their results` function would be nice, but would probably end up being quite unwieldy in comparison to just writing out a purpose-specific function for what you exactly need.
[1] - Error handling, timeouts/cancellation, maximum amount of processes running in parallel, wait-for-full-join vs. returning results as they appear, introspection of currently running subordinates, subordinate output streaming/buffering/logging, ... A lot of things to consider when you're trying to build something universal, but that are easy to solve/ignore when you're building something purpose-specific with known constraints.
Imagine if instead of that, you could do:
Of course, JavaScript having exceptions as the main error-raising approach and `await` supporting them makes that a lot easier.IMO, it is pretty much the best-of-all-worlds language that is still accessible. (Meaning not exotic like Haskell or Erlang..)
The concurrency is beautifully painless.
If you want the exact opposite of this (that is, to use JS from the shell), try https://bashojs.org
For example:
Great that it's under active development, but changes to my scripts are infrequent and slow. I wouldn't want to be touching an old script on a server somewhere saying "How do I do X in ZX again?" and everything I find online is now for v15 while I'm still on v3.
Maybe if it had plans around a LTS version I'd take a look at that stage.
To be honest though I like doing things in bash. You can get pretty far & it's 100% portable. If something's too complicated for bash it's probably time it's not just a simple CLI script anymore, in my experience.
Would you feel better if they called version three v1.9 instead?
If there are no breaking changes, then I would feel better if they called it v1.9.
Oh yeah, right, because the first thing that comes to mind when writing bash scripts is "I sure wish there was more 'await' noise in all this code!"
Anyways: 'async' in the Python and Javascript sense was a mistake, future generations will think we were insane to adopt it.
https://journal.stuffwithstuff.com/2015/02/01/what-color-is-...
Adding it to a language where IO is typically blocking with other ergonomic concurrency mechanisms, that I can imagine being somewhat controversial.
It would be good if async weren’t infectious, but as a sibling comment said that was already the case with Promises and callbacks.
It would maybe also be better if concurrency was the default behavior and keeping a reference to a promise was the explicit syntax, but I could see downsides to that. It potentially hides/encourages excessive use of expensive calls. And implicit concurrency is a potential source of many bugs.
[1] https://github.com/google/zx
They could also be parsing out the first word as the command and not using shell execution at all.
> The zx package provides useful wrappers around child_process, escapes arguments and gives sensible defaults.
lit-html and at least one SQL generating package I've seen use the template string custom interpolation mechanism to auto-escape things - it's a pretty established pattern at this point in javascript land ... but also, yes, until you learn that, it totally does look prone to injection. I've got in the habit of going and finding the template string interpolation function and double checking, because otherwise I find it hard to convince my brain to believe it isn't prone to injection and it interferes with my skim reading the code ;)
um… what?
I know a bit of bash, but I'm always looking up how to do things I know are simple in JS. I would love to be able to write scripts in JS because I'm faster with it, and I find it easier to read.
- https://tc39.es/proposal-hashbang/out.html
- https://github.com/tc39/proposal-hashbang
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
Not saying it doesn't happen, just that it hasn't been my experience.
I think these are some reasons why our mileages differ:
- I need my scripts to work in both Windows and Linux.
- I am not very experienced with bash or other shell.
- Most of my "automation work" only involves reading text from a file, transform it, and write to another file. (Generating SQL commands, doing stats about town names, etc.)
I came across Bash, Powershell, Ruby, Python, Go, Rust, Perl, but JS?
[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
https://github.com/babashka/babashka
I was disappointed this link didn't go to another ZX Spectrum emulator :(
I usually go with bash + set -euxo pipefail and if it becomes too complicated I switch to Python.
GoLang/Rust are the perfect tool when distributing tools as a single binare. Where in the world does JS fit in?