Sailfish Community News, 18th May, Busybox ash

BusyBox ash vs GNU Bash

When we released Sailfish OS 4.0.1 in early 2021, the default shell was changed from GNU Bash to BusyBox ash. GNU Bash is still available in the repositories, but it’s not installed by default. In today’s article, we will have a look at the differences between the two shells.

Short history of shells.

BusyBox ash is one of the shells included in BusyBox, the other one being hush. BusyBox ash is a derivative of the Debian Almquist Shell ‘dash’, which in turn is a derivative of the Almquist shell. The Almquist shell is a lightweight Unix shell from the 80s, originally a clone of Bourne shell.

GNU Bash is a shell included in the GNU project. It was originally written to be a compatible replacement for the Bourne shell. So it can be seen as a great uncle/aunt of busybox ash.

Same but different

GNU Bash has added several features on top of the POSIX shell standard. While we have built BusyBox ash with the bash compatibility options, there are differences. In practice this means that quite often shell scripts targeting GNU Bash need changes before they work on BusyBox ash. On the other hand, both shells are POSIX compliant, so shell scripts targeting POSIX shell should work on both without changes.

Below I will go through some differences that we have found while adapting our scripts to BusyBox ash. Please note that this is definitely not a complete list of the differences between the shell, but just some things that we have faced during the transition. Neither is this a complete list of changes made to the scripts in the process, as in many cases we have targeted POSIX compatibility, even if it’s not a strict requirement in order to work with BusyBox ash.

Here document delimiters

Let’s say you have the end delimiter of your here document on the same line as the ending parenthesis of your assignment, like this:

FOOBAR=$(cat - <<-EOF
FOO
BAR
EOF)

That is an error - “EOF” should be on a line by itself. But bash forgives this kind of errors, it just prints a warning. Busybox is not as forgiving and it will just fail.

Here strings

While BusyBox ash understands here-documents, it does not understand here strings.

In most cases it’s easy to pipe the output of echo instead of using a here string. For example, echo "${VAR}" | grep --quiet searchstring instead of grep --quiet searchstring <<< "${VAR}".

shopt

Bash includes shopt builtin for controlling and querying optional shell behaviour. BusyBox does not have such a thing, so we have to use other means.

One such use case is checking whether a script is executed on a login shell with shopt -q login_shell. One way of performing similar check is to look at the first character of arg0 - On login shells it starts with a hyphen. So, [ "$0" != "${0#-}" ] returns true on a login shell.

Brace expansion

Bash can generate arbitrary strings using brace expansion. As BusyBox does not support this, we have to write each string separately: foo{bar,baz} needs to be written as foobar foobaz.

Wildcards in string comparison

Bash allows using wildcards in string comparison. Say, you want to check if string starts with “foo”. You could simply write: if [[ "$mystring" == foo* ]]; then ... . Or, if you want to check if the string has “foo” anywhere in it, you would write: if [[ "$mystring" == *foo* ]]; then ...

With BusyBox this kind of construct is not available, so we have to use some other way of checking. There are several ways of doing this, for example using grep: if echo "$mystring" | grep -qE "^foo"; then ...

Another possibility is using substring parameter expansion, which is a POSIX feature: if [ "$MYSTRING" != "${MYSTRING#*foo}" ]; then ...

Arithmetic evaluation in conditionals

Bash allows (( )) arithmetic evaluation with conditionals, e,g if (( myvalue == 1 )); then

Again, this can be implemented in multiple BusyBox compliant ways. A simple “equals” check can use -e comparison: if [ myvalue -e 1 ]; then. If you have a more complex expression, you can first evaluate it with the let builtin and then compare the results.

Environment variables

On startup, bash sets environment variables UID and EUID to match the current user ID. Busybox does not do this. This is easy to remedy by using id -u -r and id -u commands.

Startup scripts

There are also some differences related to the scripts which the shell reads on startup. Bash tries to determine if it’s being run over a network connection - like ssh, and in such cases it reads the usual startup scripts. Busybox by default does not do this, so you might get surprising results when you execute commands over ssh. We have patched our version of busybox ash so that it mimics bash behaviour more closely, but I figured I should mention it anyway.

App roundup

It feels like we have all of life reflected in our app selection for this newsletter. Either that’s a testament to the ingenuity of Sailfish OS app developers, or an indication that my life experiences aren’t as multifaceted as I like to think. I maintain the former of course, and there’s no denying the variety on offer here, spanning a spectrum that includes maths, conversation, work and play. We hope you find something here to enjoy, and with at least one totally new app on offer here, maybe even something you’ve not tried before.

Fibonacci

Fibonacci is a new app from prolific app developer and maintainer Mark Washeim (poetaster). It’s an impressive piece of work, combining multiple elements in a dizzying array of capabilities. In many senses this is two entirely different apps: first a Reverse Polish Notation calculator, and second a programmable calculator using a C++-like language.

Let’s start with the first. Most normal calculators expect you to input expressions from left-to-right as you would on a page. But RPN is different: you enter the variables up-front, followed by the operator. This approach can take a while to get used to, but once mastered makes entering expressions fast and easy. You no longer have to worry about precedence, or operators that take more than two variables. Things just fall into place.

But this is more than just an RPN calculator. Under the hood the app is built on SymPy, a symbolic maths library that deals with algebra rather than numbers. In practice, that means you can enter mathematical expressions, simplify them, and not lose any precision until you want to boil your calculation down to a number at the end. It will also comfortably handle complex numbers too.

The second is a programmable calculator that uses the exprtk library to efficiently run simple programs using a C++ style of notation. It’s not exactly C++ and it took me a little while to get the hang of the syntax. The error messages aren’t always the most helpful. But it ultimately lets you define and execute — theoretically at least — any computable function.

Mark is very clear that this is still a work in progress. “It may eat your machine” he explains in the description “But I like it”. And so do we. At version 0.9,1 it’s already a very capable tool. Mark also has big plans for it, using the SymPy engine to perform calculus, amongst other things. This is all very promising, and makes Fibonacci one to watch.

Fibonacci is available from the Jolla Store, OpenRepos and Chum.

ChatGPT

Although we looked at the ChatGPT app from Dominik Chrástecký (Rikudou_Sennin) only a month ago, Dominik has been developing it rapidly, so we thought it would be worth heading back to take another look. When we last looked at it, it was on version number 0.9.6. It’s now on 0.9.10 having enjoyed three other releases in between.

In case you’ve not heard the news, ChatGPT is the impressively competent chat bot from OpenAI that uses a large language model to generate textual answers to any question you want to throw in its direction. It will find information for you, summarise text, answer programming problems. If you’re feeling brave it will even try to do maths, although not always with the most successful outcomes.

In general, it’s good to have some healthy scepticism about any of the answers it provides, but it’s also a multifaceted tool with potentially far-reaching utility.

The app allows you to indulge in conversations with the ChatGPT chat bot. You’ll need an OpenAI API key to do this, but the description explains how you can do this (getting one is “free as in beer”, as long as you’re not too concerned about the privacy consequences). The latest updates add the ability to use GPT-4, the latest and greatest backend, as long as your API key supports it. Perhaps more relevant for many users is the ability to switch between languages (currently English, Czech, Swedish and Polish). It’s nice to see Dominik continue to improve the app and keep Sailfish OS on the cutting edge.

ChatGPT is available from the Jolla Store, and OpenRepos.

Patience Deck

Regular readers of the newsletter will be familiar with Patience Deck from Tomi Leppänen (tomin). It provides not just a deck of virtual cards, but what you might call a deck of decks of virtual cards. By which I mean it incorporates any astonishing ninety different card games, complete with rules and explanations, all in the one diminutive app.

Back in November of last year Tomi announced a call for feedback, asking users for input to add to the app’s issue tracker. Since then he’s been working through the suggestions and gradually improving the app based on them.

This process has borne some very ripe and delicious fruit. My particular favourite is the animated celebration of exploding cards that you’re treated to if you win a game, à la Windows 95! But that’s not all. Since we last looked at the app it’s gained an improved button bar with the option to start new games as well as repeating the existing game, with new graphics and an undo option that straddles restarts.

It’s impressive stuff, and well worth the upgrade. This has to be the best card game app for Sailfish OS, and you’d be hard pressed to find something better on any platform.

Patience Deck 1.0.1 is available from the Jolla Store and OpenRepos.

Hafenschau

Samuel Kron (black-sheep-dev) bills his Hafenschau app as “an unofficial content viewer for German News Portal tagesschau”. It provides a slick QML-based interface to the news site, making it easy to pick out and read news stories — images and all — without having to resort to accessing the site through the browser.

The app provides categorised channels: domestic, foreign, economic, investigative news, and so on. You can also choose regional news stories based on a regional setting you specify directly within the app. It also has a handy search facility in case you’re looking for something specific or historical.

It’s a German news site, and so unsurprisingly the articles are in German. But as long as this isn’t a blocker for you being able to read the news stories, you’ll find the app a very worthwhile addition to your phone.

The latest updates seem to have been precipitated by service-side API changes that affected media and images, as well as updates to fix the packaging.

Hafenschau is available from the Jolla Store, OpenRepos and Chum.

Repository roundup

The network stack

The telephony stack

  • voicecall, the open source part of the calling application, Michal-Szczepaniak proposed to package again the header files, so plugins can be compiled against voicecall.

Calendar stack

Low level libraries

SDK and developer tools

Sailfish OS website

Please feed us your news

Thanks for reading! Please keep sending us the suggestions for future topics.

20 Likes

What was the reason to switch from bash to ash? It looks like it is not a trivial change on your side.

Was bash just an annoying dependency or was the switch a technical requirement?

Were your estimations of how much work it is to switch it close to the actual effort?
I imagine something like this is hard to guess.

Thanks for this nice article :slight_smile:

3 Likes

GPLv3 and (not) being able to lock phones for corporate use presumably.

1 Like

Fascinating article on busbox/bash and great to see the repository roundup back again :smiley:

Concerning the reason for switching to busybox, my understanding is that maintainability and memory footprint were both factors in the decision. @sage talked about this in the Rokua release blog post, which paved the way for the later changes.

As part of our move towards a more maintainable system we have also been switching to use busybox more widely. In this release we moved coreutils, tar and vi to busybox. An additional benefit of using busybox is that it reduces the memory footprint of our image. With the coreutils replacement we saved ~4.2MB and with tar ~1.4MB from all device images. The vim-minimal replacement saved ~1.6MB of space from images with developer mode.

2 Likes

https://irclogs.sailfishos.org/meetings/sailfishos-meeting/2021/sailfishos-meeting.2021-02-25-08.00.log.html#l-21

1 Like

      

5 Likes

I wanted to say thank you for the bash/ash article. Thanks! And also, to point out that most of the RPN part of Fibonacci stems from Richard Rondu’s GitHub - lainwir3d/sailfish-rpn-calculator: A RPN calculator for Sailfish OS It seems he was in the process of looking for a new backend and it stalled. I’m hoping he finds some time and that we might collaborate on it. I did fix a couple of bugs, add button behavior and started adding constants to the Sympy backend. But it’s still mostly his work.

On the Sympy side, I also revived ‘Limit, Derivative and Integral’ from Roberto Colistete after getting some packaging advice from @nephros. Those, with some modifications, are available from CHUM, as are mpmath and sympy. I plan to make, cough, a derivative of those, where all three, plus solve are available in one place (perhaps Fibonacci). I also want to integrate matplotlib since UTF8 Binomial output is tricky to render. The code output which is available in Roberto’s apps I’d like to expand and make more usable. The Math prof I’m consulting with suggests that the Latex output is actually the most important :0

So anyone interested in Math, please let me know if you have ideas! Thanks!

4 Likes

LOL, as if core components more than 4 years out of security support (Qt 5.6) plus the definite statement that this will not change anytime soon would be less deterrent to potential customers.

Unfortunately i think there are plenty (relatively speaking) of customers that care less about those aspects than locking, managing, monetizing and whatnot.

This topic was automatically closed after 30 days. New replies are no longer allowed.