Linux-Fu: One At A Time, Please! Critical Sections In Bash Scripts

You normally think of a critical section — that is, a piece of a program that excludes other programs from using a resource — as a pretty advanced technique. You certainly don’t often think of them as part of shell scripting but it turns out they are surprisingly useful for certain scripts. Most often, a critical section is protecting some system resource like a shared memory location, but there are cases where a shell script needs similar protection. Luckily, it is really easy to add critical sections to shell scripts, and I’ll show you how.

Sometimes Scripts Need to Be Selfish

One very common case is where you want a script to run exactly one time. If the same script runs again while the original is active, you want to exit after possibly printing a message. Another common case is when you are updating some file and you need undisturbed access while making the change.

That was actually the case that got me thinking about this. I have a script — may be the subject of a future Linux-Fu — that provides dynamic DNS by altering a configuration file for the DNS server. If two copies of the script run at the same time, it is important that only one of them does modifications. The second copy can run after the first is totally complete.

Continue reading “Linux-Fu: One At A Time, Please! Critical Sections In Bash Scripts”

A Shell? A Programming Language? Relax! It’s Both!

Every time we publish a Linux hack that uses a shell script, someone will chime in about how awful it is to program shell scripts. While we like the ubiquity and efficiency, we can’t disagree that the shell is a bit of a hack itself. [Axel Lijencrantz] wants to change your shell to be a full-blow programming language called Crush.

On the face of it, it looks like a shell. Want to see the contents of the current directory? Simple: ls.

The difference is underneath. In Crush, ls is a built-in and it returns data in rows like a database. You can manipulate that database with SQL-like commands: ls | where {type=="directory"}.

Continue reading “A Shell? A Programming Language? Relax! It’s Both!”

Linux-Fu: Help Messages For Shell Scripts And Here Documents

Imagine that you want to output multiple lines of text in Bash, or any shell script. Maybe it’s for a help string for a particularly convoluted shell script you’re writing. You could have a separate echo command for each line.  Or you could use the “here document“.

The “here document” construction takes the text between two delimiters and passes it, as if it were piped, to a command.

if [[$# == 0 ]] || [[ "$1" == "-h" ]]; then
cat << EOF
This is my help message. There are many like it but this one is mine.
My help message is my best friend.
EOF

All of the text, as written, with line breaks and spaces and all, get passed to cat and your helpful formatted message is printed to the user.

Continue reading “Linux-Fu: Help Messages For Shell Scripts And Here Documents”

Linux Fu: Alternative Shells

On Unix — the progenitor of Linux — there was /bin/sh. It was simple, by comparison to today’s shells, but it allowed you to enter commands and — most importantly — execute lists of commands. In fact, it was a simple programming language that could make decisions, loop, and do other things to allow you to write scripts that were more than just a list of programs to run. However, it wasn’t always the easiest thing to use, so in true Unix fashion, people started writing new shells. In this post, I want to point out a few shells other than the ubiquitous bash, which is one of the successors to the old sh program.

Since the 7th Edition of Unix, sh was actually the Bourne shell, named after its author, Stephen Bourne. It replaced the older Thompson shell written in 1971. That shell had some resemblance to a modern shell, but wasn’t really set up for scripting. It did have the standard syntax for redirection and piping, though. The PWB shell was also an early contender to replace Thompson, but all of those shells have pretty much disappeared.

You probably use bash and, honestly, you’ll probably continue to use bash after reading this post. But there are a few alternatives and for some people, they are worth considering. Also, there are a few special-purpose shells you may very well encounter even if your primary shell is bash.

Continue reading “Linux Fu: Alternative Shells”

Typing By Slamming Your Laptop Closed. Repeatedly

Do you sometimes feel that your custom mechanical keyboard is not quite loud enough to proclaim your superior hacking powers? Or do you need a more forceful way shout in all caps at someone who is wrong on the internet? For all this and more, [Jesse Li] has got you covered, with a set of bash scripts that allows you to type by slamming your laptop closed repeatedly, using Morse code.

Not the fastest way to type, but definitely the most forceful

The scripts are quite simple, and work receiving the lid open/close events from ACPI (Advanced Configuration and Power Interface), recording the open and close timestamp and converting the timing to dots and dashes. After slamming to the required rhythm, you keep the lid open to see the character appear.

Why would want this? Well, you can now type the letter E by closing your laptop, instead of locking it. Maybe use it to send an emergency message while you’re being held by terrorists in a B-grade action movie. Otherwise, we think this is just an entertaining little hack that’s probably the product of quarantine induced boredom.

Morse code, otherwise known as CW, is still in surprisingly widespread use by ham radio operators, because it’s good at getting messages across intercontinental distances when signal conditions are bad and CW-only ham radio gear is cheap and easy to build yourself. We’ve also covered the Koch Method of learning CW, so don’t be afraid to dabble a bit during the quarantine.

Linux Fu: Leaning Down With Exec

Shell scripting is handy and with a shell like bash it is very capable, too. However, shell scripting isn’t always very efficient. Think about it. If you run grep or tr or sort to do some operation in a shell script, you are spawning a whole new process. That takes time and resources. But there are some answers to reducing — but not eliminating — the problem.

Have you ever written a program like this (in any language, but I’ll use C):

int foo(void)
{
  ...
  bar();

}

You hope the compiler doesn’t write assembly code like this:

_foo: 
....

      call _bar
      ret

Most optimizers should pick up on the fact that you can convert a call like this to a jump and let the ret statement in _bar return to foo’s caller. However, shell scripts are not that smart. If you have a shell script called MungeData and it calls another program or shell script called PostProcess on its last line, then you will have at one time three processes in play: your original shell, the shell running MungeData, and either the PostProcess program or a shell running the script. Not to mention, the processes to do things inside post process. So what do you do?

Continue reading “Linux Fu: Leaning Down With Exec”

Linux Fu: Debugging Bash Scripts

A recent post about debugging constructs surprised me. There were quite a few comments about how you didn’t need a debugger, as long as you had printf. For that matter, we’ve all debugged systems where you had nothing but an LED to flash or otherwise turn on to communicate with the user. However, it is hard to deny that a debugger can help with complex code.

To say you only need printf would be like saying you only need machine language. Technically accurate — you can do anything in machine language. But it sure makes things easier to have an assembler or some language to help you work out your problem. If you write a simple bash script, you can use the equivalent to printf — maybe that’s the echo command, although there is usually a printf command on a typical system, if you want to use it. However, there are other things you can do with bash including a pretty cool debugger if you know how to find it.

I assume you already know how to use echo and printf, but let’s dig into how to use trace execution line by line without the need for echo statements on every other line. Along the way, you’ll learn how to get started with the bash debugger.

Continue reading “Linux Fu: Debugging Bash Scripts”