New in Bash 5.3
New Bash
© Lead Image © Laschon Maximilian, 123RF.com
Bash is more than 40 years old, but it is still an active project that receives occasional updates. The most recent version appeared in July 2025 with some important changes. We take a look inside Bash 5.3.
Bash 5.3 was released in the summer of 2025, and it came with a bunch of interesting new features. One important emphasis of the update is script performance. You can expect your scripts to run faster once you become familiar with the new performance features included with Bash 5.3.
The new release will eventually make its way to your distro's repositories, but if you can't find a package, you can always build Bash from the source code. A few preparatory steps are required before you build. The first step is to install the build-essential package. This package has dependencies on important packages such as libc6-dev, gcc, g++, and make.
As soon as you call the command
sudo apt install build-essential
your system is ready to build the binaries from the source code.
If you want to avoid messing up your production environment with non-distribution software, don't install Bash 5.3 to /usr/local/ – which is the standard procedure. Instead, put it in a new folder, such as /opt/bash/bash-5.3, that is not included in the $PATH variable and will not interfere with production operations. See the box entitled "Installing" for more on setting up Bash 5.3.
Installing
Unpack the package with tar. As is often the case – wherever the maintainers of the software have defined an autoconf – a configuration script is included. You can use this script to customize the compilation and installation phases.
In my specific case, it was only the --prefix parameter that needed some attention (Figure 1). This parameter controls the folder structure in which you install the package. I specified the /opt/bash/bash-5.3 folder I used for this article. Following a call to configure, you need to call make and sudo make install (Figure 2).
If you compile Bash yourself, note that there have been a few major changes to the codebase in the latest version. In version 5.3, Bash switched to the C23 standard, or, to be more precise, the ISO/IEC 9899:2024 (en) [1] standard. This change means that you can no longer build Bash with compilers that use the original Kernighan and Ritchie (K&R) style.
New Checks
Version 5.3 of Bash uses the first two lines of a file to check whether it is really looking at a script or possibly a binary file. As you will probably be aware, it is not just shell scripts, but also scripts in interpreted languages, such as Python, Perl, or Ruby, that start with a shebang #!. This is usually followed by the path to the interpreter, for example /bin/bash, /usr/bin/env perl, and so on.
There is another welcome new feature: If the fi keyword, which is typically used to terminate an if statement, is missing, Bash now outputs the line number of the last opened if. Previously, the shell always returned a less-than-helpful Line X: Syntax error: Unexpected end of file error message.
If you now attempt to run something like the faulty script in Listing 1, you will see a far more useful message prompted by the missing, final fi: Line 8: Syntax error: Unexpected end of file from command 'if' in line 2. This also applies to while and for loops that are not terminated by done.
Listing 1
Missing fi
#!/opt/bash/bash-5.3/bin/bash - if [ "$1" = "a" ]; then echo "A" else echo "Not A"
Friends of regular expressions also get their money's worth with the new release. Bash 5.2 accepts the following nonsensical sequence without complaint (the quantor b needs to be a digit):
[[ "$1" =~ [0-9]{b} ]] && echo "$1" || echo "Nope"and simply outputs Nope, but Bash 5.3 returns a very helpful error message: Line 2: {b}i': Invalid content of "\{\}".
New Environments
GLOBSORT in version 5.3 sees the introduction of a new environment variable that lets you control the way path name completion results are sorted. The available sorting fields are name, size, blocks, mtime, atime, ctime, numeric, or none. The sorting direction can be ascending or descending.
The source command can now be explicitly restricted to a specific path using the -p PATH switch. This feature means developers and admins can create their own environments outside of the $PATH and even reference source code inside these environments. My gut feeling tells me that this could become a very exciting topic.
Command Substitution
Old hands still like to use constructs such as lines=`wc -l /etc/fstab`, although the backtick notation is considered to be error-prone, especially when using backslashes \. It is better to use the dollar notation lines=$(wc -l /etc/fstab) at this point.
However, both these options have a decisive disadvantage. They both fork a subshell, that is to say, they launch a new process. This behavior could lead to considerable overhead if many subshells are running. A subshell can also cause confusion, for example, with the variables created inside the subshell.
Bash 5.3 comes with two new syntax elements for addressing this issue: ${ cmd1; ... ; cmdN; } and ${| cmd1; ... ; cmdN; }. These elements specify that the commands will execute in the same shell without forking.
Subshells, like the one used in the third line of Listing 2, cause the script to output File has 24 lines. The myfile variable is empty outside the subshell. Listing 3 uses the new syntax in the third line, which ensures that myfile is executed in the same context as the script.
Listing 2
Command Substitution with a Subshell
01 #!/bin/bash
02 myfolder="/etc"
03 lines=$( myfile="${myfolder}/fstab"; wc -l "$myfile" | cut -d' ' -f 1; )
04 echo "File ${myfile} has ${lines} lines"
Listing 3
${ cmd1; … ; cmdN; }
01 #!/opt/bash/bash-5.3/bin/bash
02 myfolder="/etc"
03 lines=${ myfile="${myfolder}/fstab"; wc -l "$myfile" | cut -d' ' -f 1; }
04 echo "File ${myfile} has ${lines} lines."
The second new syntax element
${| cmd1; ...; cmdN; }is less intuitive, but handles similar use cases. It is particularly useful if you want to have full control over the results of the substitution and don't mind a performance boost due to avoiding forks, and if you want to keep side effects in the current shell context (Listing 4).
Listing 4
${| cmd1; …; cmdN; }
01 #!/opt/bash/bash-5.3/bin/bash
02 #!/opt/bash/bash-5.3/bin/bash
03 REPLY="Bash-Shell"
04 myfile="/etc/fstab"
05 thefile=${| wc -l "$myfile" | cut -d' ' -f 1; date +%Y-%m-%d ; REPLY=${myfile}; }
06 echo "File: ${thefile}; REPLY: ${REPLY}"
The main difference between Listings 2, 3 and 4 is that Listing 2 uses a subshell $( .... ) in order to determine the line count. Both, Listing 3 and 4 do not. They determine the line count in the context of the running shell. This will run faster (especially if used in loops) than subshells, since it omits the overhead of forking many processes.
Listing 4 uses the new notation ${| ... }, with a pipe symbol right after the opening braces. It differs from the new command substitution by using the REPLY variable and not stdout for assigning values.
The REPLY variable is set in the second line. This is not normally necessary, as REPLY is set automatically, for example by read, if no variable argument is assigned to read. In other words, read is volatile.
In the third line of Listing 4, I defined a file to which I then applied the operations in line 4. First, wc outputs the number of lines, and then the current date is written to stdout. Finally, I assigned the filename to REPLY.
Attentive readers will notice what is going on: ${| ...; } does not intercept the standard output. As a result of the construct, REPLY is ultimately fed to the assignment. This means that thefile is equal to /etc/fstab after this line. After completing command substitution, REPLY also fields the original value, Bash-Shell. The actual benefit of the construct lies in maintaining the context, even if this is not obvious at first glance (Figure 3).
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Digital Autonomy
• The Answer Was Already on the Shelf
• Changing the Chip Industry: How Public Investment Has Grown Open Silicon
• United Nations Open Source Portal Goes Live
• EU Open Source Strategy Plays Key Role in Tech Sovereignty Package
• France Says “Au Revoir” to Microsoft
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
2,000 Vulnerabilities per Linux Release
Thanks to AI bug hunters, the Linux kernel is seeing record numbers of vulnerabilities, and it's overwhelming developers.
-
Linux Exempt from California’s Age Verification Law
So long as Linux is distributed under the GPL, MIT, BSD, and Apache licenses, the OS is exempt from being required to verify the age of its users in California.
-
Roll Out the Cake: Linux Turns 35
35 years ago, a Finnish student began a humble project that would forever change the course of technology.
-
China Switching from Windows to Linux
China has ordered several government agencies to drop a Chinese-developed version of Windows 10 in favor of either KylinOS or UOS.
-
Pine64 Halts Production of Linux Devices
With continued DRAM and eMMC shortages, Pine64 has decided to discontinue production of Linux devices.
-
The Bullet-Proof KDE Software Initiative Is Coming
KDE, Techpaladin, and Kubuntu Focus have announced a new initiative that will provide at least three years of support for KDE Plasma 6.6 LTS and related software.
-
Linux Mint Shares a Possible Kernel Cleanup Solution
For those on Linux Mint who like to keep multiple kernels around but don't want them to take up too much space, you might be getting a new automated tool.
-
CachyOS Gets an Update
CachyOS August 2026 release is now available with the latest version of KDE, some new features, and plenty of improvements.
-
The Linux Kernel Dev Staging Area Now Rejects AI-Generated Patches
Unless a kernel patch is a valid security fix, it will be rejected if it was created using AI.
-
Linux Surpasses Double-Digit Market Share
According to two sources, the Linux operating system has hit a major milestone in market share that naysayers thought would never happen.
