8 ms·
ZX – A tool for writing better scripts
- hanselot 3y agoI'll be honest, I did not pass the word Javascript. And I don't think I could be convinced to. Didn't expect people to be so hurt by the truth. Sorry. I just don't trust JS running on my machines.
- deleted 3y ago[deleted]
- az09mugen 3y agoJust another language Google tries to push, it doesn't really solve anything Python/JS/Bash et all can already do. Remember Carbon who was supposed to replace C/C++ ? I may be wrong, but I think it will be the same pattern as Carbon here.
- liampaul 3y ago[flagged]
- jauntywundrkind 3y agoI really really enjoy using zx. As a dev it lets me get back to a good scripting language, where I process input, run other programs, emit output. Powerful & succinct. As a tool maker, it helps me show my work. Many of the common tasks like running an script or calling fetch will by default log what's happening in clear format, pass through the activity. It's fantastic to write these devtools that do a bunch of tasks, but are showing their work at every step. If something goes wrong, the person immediately sees the evidence of what was ran & what the output was. It helps close the iteration loop very effectively. Zx makes such a huge difference, while being little more than a couple small good ideas to help node.js be more shell-scipty. Good stuff. I haven't tried Dax, another scripting system atop js, but I see zx glowingly mentioned in it's recent submission. https://news.ycombinator.com/item?id=39315689 https://news.ycombinator.com/item?id=39315689
- pmontra 3y agoAn immediately visible problem with zx is that wrapping commands in $`` makes it harder to copy and paste them back and forth to the shell to test them. Did that slowed you down sometimes or added an occasional bug?
- hiAndrewQuinn 3y agoThis looks really cool, actually, and I'm surprised I haven't heard of this before. My incorrect gut intuition is that JavaScript devs usually don't do very much in depth terminal level command work, but that's of course false on a Bayesian level. There are far more JavaScript developers in the world than there are even Python developers, to say nothing of the long tail of even less popular languages. If 30% of JS devs are heavy terminal users, and 80% of (say) Perl devs, that 30% will still swamp the 80% in terms of absolute numbers. Hell, that's half the point of Node. Can't believe my gut isn't keeping up with my head here!
- TJSomething 3y agoMy big use case for this is that it's quite good for glue scripting when you're already in the context of a JS shop. My common use cases are tooling setup, CI scripts, and API response sanity checking.
- from-nibly 3y agoHere's an anecdote to help your gut. I'm a platform engineer who's favorite language is Typescript. I LIVE in the terminal. The only reason I use vscode is cause it's easier to put him into vscode than it is to put vscode into vim. Otherwise I'd be in the terminal for everything but browsing.
- a_wild_dandan 3y agoLikewise! I use TypeScript everywhere possible, and zx is a godsend. Unfortunately, I've recently dealt with gobs of Python for ML software. After years of writing TypeScript, it's been a...sobering reminder of many painful coding issues that I'd forgotten even existed. Made me deeply appreciate what TS gives us haha.
- dash2 3y agoWould a python developer feel the same in reverse?
- deleted 3y ago[deleted]
- visarga 3y agoThis feels like it could be learned in an hour and looks so nice. Wonder if it can be used with inline code to process line by line stdin.
- metadat 3y agoRelated story from today: Dax – Cross-platform shell for Node.js https://news.ycombinator.com/item?id=39315689 https://news.ycombinator.com/item?id=39315689 (12 comments)
- Dibby053 3y agoMaybe the example doesn't do justice but it looks more complicated than simply using "&" and "wait".
- liampaul 3y ago[flagged]
- pmontra 3y agoYup, it seems the perfect example to wonder if a language with async by default is appropriate for the use cases of bash scripts. The example runs 7 commands and has to explicitly await for 4 of them. The other 3 can run in parallel and it awaits for the end of all of them, which is fair. The typical bash script is sequential and I fear that its zx replacement will be an exercise of writing await, await, await. I'd go with an await by default language and wrap parallel code in whatever that language offers to wait for the end of child processes.
- Cyberdog 3y agoPlease don’t make me install Node.js to run your shell script.
- from-nibly 3y agoJust use nix-shell
- bemusedthrow75 3y agoYeah that wouldn't be great. But: This feels to me like it might be a really useful tool to do systems-integration work around an app that is built in Node.js. For example, to integrate with incrond or cron, or get a supervisor task into JS. The smallest sensible "shell-ish" wrapper that gets you access to your codebase in JS and stops the coding effort being divided so much between technologies.
- Cyberdog 3y agoSure. But I can easily see this becoming the default way to write shell scripts in the near future in the same way Electron is becoming the default way to write desktop applications.
- zeristor 3y agoZX? Is there a rainbow bar over the bottom right corner? Do words appear when you press each key?
- Fragoel2 3y ago"[For writing complex scripts] JavaScript is a perfect choice". Not sold on that. Why should I choose it over Python, PHP or others?
- chupasaurus 3y agoThis [pun very much intended]
- rrr_oh_man 3y agoWhere's the pun in that?
- justech 3y agoI’m assuming it’s this https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... (no pun intended)
- thewisenerd 3y ago`this` in javascript
- cerved 3y agoIt's asynchronous, which is pretty neat
- RandomBK 3y agoThanks, I hate it. * I love the idea, and I'm interested to see more progress in this direction. * I'm not a huge fan of the syntax - for me, the commands are the star of the show, while the async/await is a glue. This syntax emphasizes the async/await while the important stuff get shuffled into quotes. * Don't make me install node - and especially not system/user-wide packages - to run a script. Having said all that, this is a neat idea and a cool hack on top of javascript language features.
- qalmakka 3y agoWhen my shell scripts get too large, I usually switch to Perl. Still best in class at handling text processing with a few shell commands here and there.
- amitizle 3y agoI'm doing that with Ruby, and tgrought the years, it became also true for scripts that are fetching data, iterating over JSON objects, etc.
- lambdaba 3y agoWhat makes Ruby great for this is you can specify dependencies inline require 'bundler/inline' gemfile do source 'https://rubygems.org' gem 'json', require: false gem 'nap', require: 'rest' gem 'cocoapods', '~> 0.34.1' end
- theanonymousone 3y agoI do the same, in Python. I do my best to keep it zero-dependency to maximise portability.
- pk-protect-ai 3y agoNo way. If your script requires something more complex than what is difficult to implement or maintain in bash, then it is no longer just a script. Regardless of how small the resulting application may be, you should treat it as an application and not merely a script. Node.js is not typically used in the system layer where Bash scripts are commonly employed. No single administrator would replace Bash with Node.js. For parallel execution and asynchronous operations, tools like ansible exist, along with python, which administrators are already familiar with.
- LispSporks22 3y agoBit verbose for me with all that promise/await stuff. Substitution rules probably simpler tho
- mariansam 3y agoHow does this compare to the recently released Bun Shell?
- skavi 3y agoOne (admittedly obvious) difference is that it runs on Node/V8 instead of Bun/JSC.
- Jarred 3y agoBun Shell implements a cross-platform bash-like shell, using builtins for popular commands like `rm`, `cd`, `which`, `ls` etc which support the same flags on Linux, macOS, and Windows. A lot of why we made it was for `bun install` to work on Windows without needing polyfill packages like `rimraf` or `cross-env` in package.json scripts. zx uses the system-provided shell, which means it isn't cross-platform For the commands Bun Shell implements as builtins, they typically run something like 10x - 20x faster than in zx on mac/linux because spawning processes is expensive (even more expensive on Windows)
- 65a 3y agoBut...why?
- oopsthrowpass 3y agoWTH is this, some training program how to write await for no reason? :)
- m1keil 3y agoSuspect there is one in any language. Here's python's option: https://sh.readthedocs.io/en/latest/index.html https://sh.readthedocs.io/en/latest/index.html
- khimaros 3y agorelated: https://github.com/tusharsadhwani/zxpy https://github.com/tusharsadhwani/zxpy
- javaunsafe2019 3y agoI just feel relieved that the majority here also seems to think this doesn’t make sense
- Sammi 3y agoIt makes most sense if you're already using js and you need cross platform support in your scripts.
- carlwiedemann 3y ago“Ruby - A tool for writing better scripts”
- tehdely 3y agoUseless use of cat in their example script. This is not a serious piece of software.
- dspillett 3y agoMaybe the example is intended to be familiar to people who are not script experts? (rather than an example of how to do things perfectly, according to rabid accolytes of the church of demogification?)
- teo_zero 3y agoThe first command of the first example is a cat|grep... How can I assume the author is an experienced script writer? In any case, ZX replaces some of the shell's usual quirks with its own different quirks: you have to manually expand * with glob() and ~ with os.homedir(), you can't build commands as strings without repeated calls to push(), etc.
- dspillett 3y ago> example is a cat|grep... How can I assume the author is an experienced script writer? Perhaps because they are writing documentation that can be understood be less experienced script writers as well as themselves, using a very common example seen everywhere? I find "cat full | ..." keeps the left-to-right flow of a command nicely, and is better understood by those less familiar with shell work than prepending "< file " which I've seen cause confusion.⁰ Yes, it is an extra process. Yes this is less efficient, both due to the fork and the extra IPC along the pipe. But even under Windows where spawning a process is massively more costly than other OSs¹, if you are that worried about this bit of inefficiency² then perhaps you have picked the wrong tool for the job in using a shell/script in the first place?³ > with its own different quirks I agree there. Though I can see that for some, starting from already using JS via node, this might be an acceptable trade-off. -- [0] I sometimes also use it in part to wind up the cult of demogification, because they seem to both want to be wound up and deserve to be wound up :-) [1] Complain to MS about that, not me and my script/one-liner. [2] Are you using it in a tight loop? Maybe if you are doing something over thousands of files, but then the resources used by the something likely dwarf the cost of cat into irrelevance. [3] A question that suggests the supplementary: are you an experienced <whatever>?
- teo_zero 3y ago> I find "cat full | ..." keeps the left-to-right flow of a command nicely Sorry, I don't buy it. You don't read files like this: cat file | less And you don't compile C programs like this: cat hello.c | gcc -xc - Actually using less, grep (and even gcc) as filters is more confusing to "those less familiar with shell work".
- eviks 3y agoNeither is bash great, nor is JavaScript a prefect choice, and the examples are pretty underwhelming with all the inconvenient escapes and keywords
- Mawr 3y agoWell this doesn't make much sense. If you rightfully find bash inadequate at some point, just switch to the next most natural tool - Python. Nobody's going to be surprised when they see a Python script. If you start feeling Python is inadequate too, then: 1) You're wrong, just stick to Python 2) If you're so bent on doing away with familiarity, at least get as much leverage as you can in return and use a "proper" language, like Go / Rust. You get static typing and easy to deploy binaries, which are solid benefits. Trying to use JS here is the worst of both worlds. Nobody expects to see JS in this context and it doesn't bring much to the table.
- mattlondon 3y agoPython has been banned in many places for this sort of thing in my experience. There is just too much shite and baggage associated with python environments for it to be reliably portable between systems. Anaconda that, pip this, 2.x, 3.x, string support. It's a dumpster fire. I am not saying JavaScript is any better, but python is actively considered harmful for this use case in many places I have been.
- vincnetas 3y agoin my case im usign groovy scripts with grape dependencies. script is always selfcontained single file. max portability in JVM world. no need to fiddle with dependencies.
- drowsspa 3y agoHonestly this looks better than Python. I hate all the subprocess.run([...], check=True, universal_newlines=True) and then you have the manage the dependency hell of virtualenvs. At least with node the node_modules is right there.
- ambigious7777 3y agoYes, but this isn't made for general scripting. This project seems to be aimed at JavaScript projects, for example calling zx from package.json/scripts/start If I had a JavaScript project, and I wanted to migrate my scripts away from Bash, I wouldn't pick Python. Not only would it be another language, I would also have to configure Python to run correctly, ie add it to my Docker image. Simply installing another NPM package, rather than include an entire other language is a much better and simpler solution.
- bandergirl 3y agoIt looks like people don’t get it. This isn’t “better” than your tool of choice. This is a tool for JavaScript developers to write non-trivial scripts in a portable way without getting lost in POSIX hell. Who came up with this stuff? https://stackoverflow.com/a/13373256 https://stackoverflow.com/a/13373256 If you can write shell code, Perl, Python, COBOL, suit yourself. This is for JavaScript developers in JavaScript projects.
- Vinnl 3y agoHere's an example: https://gitlab.com/vincenttunru/penny/-/blob/main/scripts/build_server_ui.mjs?ref_type=heads https://gitlab.com/vincenttunru/penny/-/blob/main/scripts/bu... That used to be a shell script. But this I can way more easily read (even after not touching it for a long time), I get autocompletion, and I can use the APIs I'm already familiar with. It's a pretty neat QoL improvement for me specifically.
- elygre 3y agoWhat’s with all the await-stuff? Couldn’t it be written just straight forward?
- Vinnl 3y agoThat allows other code to run while e.g. files are being moved. It indeed can be somewhat painful ([1] is the classic criticism) and in shell scripts is not as beneficial. I think there are even sync alternatives (i.e. equivalent functions that don't need `await`) for most of them, but again: these are the APIs I'm already familiar with, which is the entire point - and thus the await-stuff comes naturally for me, because I intuitively know those APIs are async. [1] https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ https://journal.stuffwithstuff.com/2015/02/01/what-color-is-...
- imglorp 3y agoYes and a shell script would do it with one &, while this goop is a mountain of async, nesting, futures management, and boilerplate. No thanks.
- hulitu 3y agoVery nice. You need three clicks to get tho the documentation, yet they don't explain anything. What does the const line do ? The best thing however is that it is not supported by Google.
- ambigious7777 3y ago> What does the const line do ? To declare variables? > The best thing however is that it's not suppported by Google That's the case with many things like zx.
- acoward113472 3y agoheh.. this is the engineering culture at Google. You identify a problem that bothers you but perks your interest to solve, and then dedicate 1 day a week to solving it, and then releasing it as an internal library. then get approval to open source it and do so.
- hlandau 3y ago>Write your scripts in a file with an .mjs extension in order to use await at the top level. If you prefer the .js extension, wrap your scripts in something like void async function () {...}(). Shebang scripts shouldn't have a file extension in the first place, so requiring one here is a dealbreaker. And having the file extension be used to switch between two different incompatible source formats is really a terrible design.
- xboxnolifes 3y ago> And having the file extension be used to switch between two different incompatible source formats is really a terrible design. Isn't that what all file extensions do? Distinguish between incompatible formats?
- hlandau 3y agoI've very rarely seen, say, image viewers which can't handle a JPEG with a .png extension or vice versa, but they're badly designed. Most handle this from the file magic automatically. Keying on extension is definitely an antipattern IMO. I don't see people naming C++ files .c++03, .c++11, .c++17. I don't see people naming Perl files .pl-strict-mode. Yes, it's normal for people to use file extensions, but having programs impose forced usage and semantics to them is a crutch and a sign of bad design. How am I supposed to put a script written using this tool in $PATH? This bad design seems to be a thing in the TS/JS ecosystem now. At least some language ecosystems (Deno? Not sure.) seem to be encouraging people to do 'import ".../Foo.ts"'. Which is abysmal: Firstly these are URLs, yet file extensions are against web principles and good URL design. Secondly they couple a consumer of a module to what language the module was written in and expose this as part of an API, which is terrible design.
- okamiueru 3y ago> How am I supposed to put a script written using this tool in $PATH? Separate file that invokes sh or bash and calls the script file with zx and the path to the mjs file. Should do it. Though I agree with your objection. The requirement for specific extension while also suggesting a shebang, breaks conventions and expectations. From what I can tell from comments made, it's done that way because they prefer it. Which... is a bit silly. But to each their own.
- ulrischa 3y agoI would say this is the missing Part to use npm scripts effectively
- 1vuio0pswjnm7 3y ago"Bash is great, but when it comes to writing more complex scripts, many people prefer a more convenient programming language." https://google.github.io/zx/getting-started https://google.github.io/zx/getting-started I read this and think "1. Bash is not great. 2. Why assume that I want to write complex scripts." I like simple scripts. I am embarassed by any complexity. It is the mark of a cluttered mind. As it happens, there have been and still are others that dislike complexity, though they may be greatly outnumbered. Right now there is another submission in /active on HN titled, "A 2024 Plea for Lean Software. Why Bloat is Still Software's Biggest Vulnerability" "I want to end this post with some observations from Niklaus Wirth's 1995 paper: "To some, complexity equals power. (...) Increasingly, people seem to misinterpret complexity as sophistication, which is baffling-the incomprehensible should cause suspicion rather than admiration." I've similarly observed that some people prefer complicated systems. As Tony Hoare noted long ago, "[T]here are two methods in software design. One is to make the program so simple, there are obviously no errors. The other is to make it so complicated, there are no obvious errors." If you can't do the first variant, the second way starts looking awfully attractive perhaps." And scripts are not even systems. The idea of intentionally creating "complex scripts" is indeed baffling. The HN title could be something like "ZX - A tool for writing complex scripts". Or "ZX - A tool for writing better complex scripts". Instead it's "ZX - A tool for writing better scripts".
- msla 3y ago> I am embarassed by any complexity. It is the mark of a cluttered mind. It is the mark of a cluttered world. Sometimes, there is no simple solution. You have to parse this file, you have to use software to do it, and you can't fix up every little quirk in the file's actual grammar versus the grammar you wish the file had. Tag soup HTML is one example, but there are thousands of others, around the world, doing important things for business and education. Sometimes you get to parse JSON. Sometimes you have to parse SQL.
- tester457 3y agoIn my opinion any bash script longer than a one liner is complex and should be rewritten in another language. Too many footguns.
- dang 3y agoRelated: Zx 3.0 - https://news.ycombinator.com/item?id=28195580 https://news.ycombinator.com/item?id=28195580 - Aug 2021 (163 comments) JavaScript for Shell Scripting - https://news.ycombinator.com/item?id=27072515 https://news.ycombinator.com/item?id=27072515 - May 2021 (181 comments)
- mkl 3y agoAnd similar: The Bun Shell - https://news.ycombinator.com/item?id=39071688 https://news.ycombinator.com/item?id=39071688 - Jan 2024 (225 comments)
- srid 3y agoAnd tangential: Nushell (300-400 comments), - https://news.ycombinator.com/item?id=20783006 https://news.ycombinator.com/item?id=20783006 - https://news.ycombinator.com/item?id=27525031 https://news.ycombinator.com/item?id=27525031 - https://news.ycombinator.com/item?id=33419944 https://news.ycombinator.com/item?id=33419944 Ask HN: Are alternative (oil, nu, etc.) shells usable as daily drivers? (141 comment) - https://news.ycombinator.com/item?id=34722208 https://news.ycombinator.com/item?id=34722208
- msla 3y agoGoogle is trolling us with the useless use of cat right there in the first actual line of the script. https://porkmail.org/era/unix/award https://porkmail.org/era/unix/award
- ggambetta 3y agoFor a moment I thought this would have something to do with the ZX Spectrum. I'm disappointed :(
- x-cmd 3y agoHello everyone, I think I happen to have some experiences to share: 1. Five years ago, I developed my own version of zx/dax version using TypeScript. I call this project TypeShell. 2. In the past three years, I have written x-cmd, implemented by posix shell. Please visit x-cmd at https://x-cmd.com https://x-cmd.com. It is now close to the public beta version. It is still under construction, and the demo can tell some stories. It tries to enhance posix shell in various ways. Its installation tar.gz package is only 1.02MB (which can be optimized). Even with sh/awk/curl, it can do a lot of things. These features are called modules. And, through the self-contained pkg manager (do not require priviledge to install), x-cmd can gain capabilities from existing binaries and other script projects, becoming increasingly powerful. --- The main reason I gave up TypeShell project was that the startup time became a problem. At that time, node 8 was mainstream, and node 10 had just become LTS. I remember that even using node 10, the startup time was poor compared to python/perl. In addition to startup performance, size matters. I work on different servers and must carry a 20MB node/typescript zip package to run js script. This was acceptable to me, but I couldn't help thinking, what if the solution was only 5mb. Then I tried to rewrite it in golang, and got a version with a smaller startup time and size. Unfortunately, as I understood bash more deeply, I found that basic functions could be easily accomplished through bash and curl. When I was halfway through, I realized that bash was not available in some places. I challenge to rewrite it with posix shell and awk. After years of effort, x-cmd is almost ready now. --- Friends, I'm not saying that tools like zx are not good. I do like to write some scripts using js/ts. I believe pythoners prefer https://xon.sh/ https://xon.sh/ . Perl is interesting. Fish is friendly. However, I believe posix-shell has its own advantages. The balance among size, code length, and expressiveness. I think the only possible competitors are tcl and perl, maybe lua. But none of the above is included by default in all server/container environments. --- I wouldn't advise using posix-shell due to its numerous potential issues. I think people should write scripts using the language and library they are familiar with, and do it for fun. Friends of js/ts use zx/bun-sh/..., pythoners use xon.sh, etc. Engineers can use x-cmd like `x <your-script>.[py|mjs|lua|...]`. Then x-cmd will automatically help you download the script runtime, scripts, and install dependencies before running. This is the future I have always wanted to achieve.
- hacker-l 3y ago
- up2isomorphism 3y ago“ Bash is great, but when it comes to writing more complex scripts, many people prefer a more convenient programming language. JavaScript is a perfect choice, ” I am not sure you can call js “convenient “.
- liendolucas 3y agoIf I want to write better shell scripts I usually run shellcheck and adjust accordingly or if I need facilities not provided by the shell I switch to a full fledged programming language. And oh yes, `sh` is present almost on every BSD and Linux box for free so I consider it an important thing to at least be comfortable with. shellcheck: https://www.shellcheck.net/ https://www.shellcheck.net/
- ThinkBeat 3y agoI get the utility of it, and probably having everything in the repo of a project in the same programming language is a benefit, when onboarding new people. but... Shell scripting has a long and glorious history, filled with incremental improvement in the tooling that have proven themselves over decades. The shell scripting languages themselves and all the awesome tools that come along with them on UNIX. You are 100% guaranteed to be reinventing the wheel over and over (and poorly) if you write shell scripts without a good understanding of what is available "Off the shelf" There are great benefits to had by using am appropriate language for the task at hand.
- furyofantares 3y agoGPT4 makes it so easy to write or translate scripts, I don't care if you write it in js or bash or powershell or batch files or python or ruby or whatever. Whatever is most convenient at the time is best, and it can be very easily translated if something else is preferred later.