What scripting languages come out of the box on Debian 12?
hiandrewquinn.github.io
hiandrewquinn.github.io
But it is.
Perl and awk one liners are very common. Bash is used everywhere you have the (controversial) `sudo curl .. | bash -` install method.
Ansible, if I'm not mistaken, requires python3 installed on remote hosts.
If your environments are homogeneous enough, and you don't have a large matrix of operating systems, you should definitely use this advantage.
The troubles start when you have very heterogeneous environment, custom or hardened Linux distros and etc.
It might seem like this is not being utilised as much nowadays, but I suspect it's because the "classical" Linux sysadmin roles are rare and you don't hear about it as much.
I assume everyone already knows that, but shellcheck is great help if you need to go all the way down to POSIX since it will detect /bin/sh shebang and warn about any non-compatible bash-ism.
I think the odd one out was really Apple, which ran Bash as the standard shell for many years (a choice they probably regret), while most the rest of the userland was largely from BSD.
It is not a requirement. There is the raw module that just sends commands over ssh . But if you want to do anything beyond basic most people use raw just to install python so they can use other modules which require python.
The author laments the decline of such knowledge, but the proliferation of containers, combined with the marketing efforts of the large cloud providers has reduced the number of people who work with servers directly.
I should say that this knowledge can be useful in certain niche situations, though. For example, I recently learned that GitHub Actions pulls in a basic set of utilities by using complicated distro detection[1], and Gitlab runners similarly pulls in a Docker image with git just to clone a repository!
Instead, the proper way to address this situation would be to compile static binaries, that, by their very nature, become distribution agnostic. The only reason I assume this wasn't pursued, I assume, would be that the developers working on this weren't even aware this was an option.
It's the reason I've been maintaining a small set of packages[2] that I mount into every CI container for my personal projects. I'm also quite hopeful about the cosmopolitan project[3] that builds fat binaries which can bridge this gap, although as I discovered, some containers even lack tools like gzip (which cosmopolitan depends on), so maybe static binaries it is.
[1] https://www.youtube.com/watch?v=9qljpi5jiMQ
Thats only true if you do not depend on glibc, which some statically compiled binaries still do. And even then, you’d have to rule out anything that requires newer sysalls or platforms that don’t offer stable ABI guarantees (Linux is actually the edge case here in that most kernels offer no guarantees).
It’s certainly doable though.
Have a look at the nightmare recipes for libc. On the other hand they do provide the basics of how to ship a custom libc loader across heterogeneous machines but it gets complicated fast and not something any non specialist can do in an hour.
In my experience anybody saying to compile statically does not know about the libc limitations. When they find them they hand wave, I smile and say be my guest.
By the way 2.17 is an appropriate version to target. RHEL6 much? :D
We used https://crosstool-ng.github.io/docs/ to create a cross-compilation toolchain that runs on modern debian, but produces executables that only need glibc 2.17. The only downside is that you no longer can simply apt-get a library you need -- all dependencies shipped along with your application also need to be built with this cross-compiler.
God, I hate glibc so much. It’s an absolutely terrible design from the 80s. It can and should be trivial to target any arbitrary version of glibc. The way Linux performs linking is so bad and so much worse than Windows. (Headers + thin import lib. Linking expecting a full and complete so is stupid and bad.)
Zig solved this problem. It can trivially target any version of glibc and cross-compile. It’d be nice if the Linux community demanded this level of functionality from their toolchains. Alas. https://andrewkelley.me/post/zig-cc-powerful-drop-in-replace...
What Zig does is goes way way way out of it's way to compile import libs which contains all of the exported functions but the implementations are empty.
So you aren't wrong. But the point is that the monumentally large Linux ecosystem does not work that way. Which is a real shame.
Of course, new code may actually need features from newer libc, and often you won't be able to frankenstein your way out of it with no-op plug functions and copypasting successfully.
There's also a random page on the internet with a barebones cross-distribution compatibility guide:
https://gist.github.com/wagenet/35adca1a032cec2999d47b6c40aa...
In general, “community support” shrinks to “ride on what Red Hat provides”.
The actual dependency is 2.14, when a faster memcpy was added, 2.17 is just whatever I happened to have around back when I compiled my stuff, I just didn't change anything since then, bits don't rot.
Most operating systems don’t provide guarantees about ABI stability between versions, instead mandating that libc (or other user space APIs) are the intended interface to syscalls.
Because if this, you can often come across statically compiled executables will still depend on glibc while inlining stuff like libpng.
> if you depend on glibc... things can still break, e.g. when compiled on too new glibc it fails to run on older versions.
That’s the point I was making ;)
> platforms that don’t offer stable ABI guarantees
If we're talking about Windows, the Win32 ABI is considered stable, which would also suffice for what I'm looking for, which are portable binaries that can be run on almost any version of a system.
So it has C++ and so needs a C++ stdlib. Dynamically linking is annoying so what if we statically link it? Oh but GNU's C++ stdlib wants glibc and has versioned BS and so even statically linking the C++ bits isn't ideal. And as mentioned statically linking glibc is a big no no.
So:
a) build a musl and install it in a prefix
b) add a few bits (some headers and C runtime objects) and turn it into a sysroot
c) build llvm's libc++ libunwind and a couple others, linking against that sysroot, and install it in the sysroot
d) build our shared lib, statically linking against that sysroot
The result is a shared lib that is self-contained except for the C stdlib, and any reference to the C stdlib has no GNUism nor glibc version. The trick is that musl is essentially a subset of glibc + there is no such thing as a musl-ism per musl's design tenets + the C ABI is stable enough. I don't recall us statically linking to musl - IIRC the trick is just to not have any GNUism at any level, in a way it also working in musl is kind of a happy side effect - but maybe I'm wrong.
As a consequence it works on all glibc versions and musl as well, and is entirely independent of the system's preferred C++ stdlib.
A requirement though is to load the shared library with RTLD_LOCAL (to not accidentally make internal symbols available to the outside) and RTLD_DEEPBIND (to not accidentally pick external symbols instead of internal ones)
Cosmopolitan is an extreme outlier because it deliberately replaces the need for glibc. Your typical C or C++ program isn’t going to do that.
> If we're talking about Windows, the Win32 ABI is considered stable,
We are talking about most Unixes. macOS, OpenBSD, etc.
Nowadays you even have younger developers praising static linking, as if this wasn't what we had around since the invention of the first linker, and dynamic linking only became mainstream in the 1990's.
Naturally only knowing Linux, GCC and glibc doesn't help.
It's amazing how low-brow condescension passes for wisdom. Let me give you a hint: ontogeny does not actually recapitulate phylogeny. So just because you have some vague memories of previous iterations of a technology does not mean that it's the same thing being discussed today
Modern Internet is much more friendly than Usenet forums, if you get my point.
I have to say that in my experience for a specific use case of a highload c++ daemon, nothing beats the simplicity and reliability of the static binary with musl. You only want to deploy one thing, you have nothing to share, furthermore you wouldn't want to share anything for the sake of control. So many things to worry about and to waste time on just disappear. When things are on fire having less variables to check is gold.
> the proper way to address this situation would be to compile static binaries
Nix is the proper way to address this. We'll get there eventually anyways, might as well bite the bullet now.
I think we also need to separate "Nix" from "The General Approach that is implemented by Nix (and Guix etc.)". I think the "The Nix Approach" (as I'm now going to call it) is fantastic and really is the solution to a lot of problems that we have. I think that the actual implementation of Nix isn't great and painful to use in real life.
This is not always possible, since people may have workflows based on different containers or OSes. I (and the author of the article) want to have tools that work across different environments.
> The General Approach that is implemented by Nix (and Guix etc.)
"Reproducible builds" or "hermetic environments" are commonly used adjectives for this, although they are not limited to these two tools either; Bazel from Google does it too, for example.
Yes, exactly what Nix does.
But some kind of repeatable environment is needed, traditional package management is just pure insanity where everything only works on one specific version.
Snap/Flatpak are broken by design, future tech won't need crutches like these.
They don't have very good deduplication but that's a fixable issue.
[It's still not a completely fixed problem - Nix needs to finish their content-addressable scheme, and for that you need reproducible builds; this is a detail, though.]
$ apt-cache rdepends --installed sed
sed
Reverse Depends:
xml-core
fuse3
Anyway, sh, awk and sed are there because it is mandatory: https://en.wikipedia.org/wiki/List_of_POSIX_commandsPerl and Python seems to support a lot of OS userland.
If you have GNOME, you probably have the gjs command too. It's a JavaScript interpreter.
I can’t recall if it’s part of Debian base though.
Being sent down into the field, rescuing whatever random server used by a customer, meant being able to use whatever was there, and between ed and vi, better vi.
I remember I used to use Debian instead of Ubuntu b/c a minimal install didn't include Python
If they count sed, they should definitely count vimscript !
The only one I can think of is TypeScript where it builds source maps to help debug the underlying JavaScript without having to see it.
Turns out not every deployment scenario needs a compiler, and it is still an opportunity to make money outside the FOSS world.
Debian provides two packages python-is-python3 and python-is-python2 to restore the /usr/bin/python.
Plan on installing your own so that you can control versions, libraries, and packages.
(Yes, this post is about "in extremis" dev where you may not be able to do this. Still.)
Python's standard library covers most scripting use cases, even HTTP networkingand it's stable you can write script and forget. No need to "control" stuff. For example I am using minimal python script + cron for updating letsencrypt certificates in misc linux distros. Everywhere it's system python out of the box without any additional dependencies or virtualenvs.
Still trying to decide if it's worth going to Rust for script'ish type work, I have a feeling it's not quite the right choice.
Of course you can depend on zsh/bash, but then the Apple UNIX tools are BSD flavoured, not GNU flavoured like on Linux, so Linux shell scripts will also quite often not work out of the box on macOS.
The trouble usually starts when a program needs some third party library. So maybe the rule is more like: the system libraries are for the system, not for you. Unless, of course, they are -dev libraries. I do believe modern Ubuntu won't even let users pip install stuff, which should improve things (Gentoo has been configured like this for years).
pip works fine if used in a venv. They finally blocked installing stuff system wide because it was creating mess.
Even used in a venv pip creates a mess as people start creating ad hoc environments and don't really know how to recreate them (cause of many "works for me" type problems). I always advise people to take the extra step of adding a new dependency to pyproject.toml or requirements.txt and then doing `pip install -e .` or `pip install -r requirements.txt`.
If the developer of the script is targeting that platform, it is exactly the expected version.
Perhaps you should stop using libraries that break API compatibility very often, since it's an indicator of low skill of the authors.