Hi folks!
Here's some more BASH snippets I've happened across since my last post. Hope you find some of them of use!
Find BIOS version via CLI
I'm sure that many of you will have heard of using dmidecode to do this. I've always found it to leave out critical data myself, so set out to find a better way to do it. Lo and behold, I came across this site, which detailed the following method of grabbing the BIOS's details directly from RAM. Here goes:
dd if=/dev/mem bs=32768 skip=31 count=1 | strings -n 10 | grep -i bios
This reads 32k of your RAM, from 32*32k (1048576 bytes) onwards, then strips out anything but human readable strings at least 10 characters long. It lastly searches for any line containing the case-insensitive string "bios". Personally, I found that this came out with far more useful information than dmidecode ever could, without serious amounts of messing about, when working with different manufacturers' boards.
Intercept the stdout/stderr of a process
This is one of the many uses of strace, which I've found to be an invaluable debugging tool. Have you ever been SSH'd onto a machine, and needed to read the console output of a command which is running on the remote machine? This is a perfect way to read its output, particularly if you can't find the terminal it's attached to. The command simply intercepts any call the process makes, which would cause it to write to file descriptor 1 or 2 (stdout, stderr).
strace -ff -e trace=write -e write=1,2 -p SOME_PID
Until loops
One of BASH's lesser known loops is the until loop. Its behaviour can be emulated in a number of ways with better known functions, but 'until' is an incredibly readable, and succinct way to achieve the repetition of a process until a certain point. Here's an technical example using ping's return code to hold up a script:
until ping -c1 www.google.com; do
echo "Unable to reach www.google.com"
sleep 20
done
echo "Successfully pinged Google!"
Edit a file in place with sed
I didn't know about this option until very recently, and had a number of massively inefficient scripts because of it. It's a simple command line parameter, which allows you to edit a file with sed, rather than just output it to a new file. Check it out:
sed -i '' -e 's/foo/bar/g' {FILENAME}
Wasn't that so simple? The documentation for this process is slightly misleading, however. The man page states "-i - edit files in place (makes backup if extension supplied)". This does not mention that you must include a zero-length extension, if you do not want a backup, hence -i being followed by two single quotes.
BASH Emacs mode to speed up workflow
By default, BASH is configured to be in Emacs mode. This means that you can use Emacs-like Ctrl+Letter commands to speed up your workflow. Here's a list of the various commands you can use:
Ctrl+a Move cursor to beginning of line
Ctrl+e Move cursor to end of line
Ctrl+w Cut the last word
Ctrl+u Cut everything before the cursor
Ctrl+k Cut everything after the cursor
Ctrl+y Paste
Ctrl+_ Undo
I find the most useful of any of these to be "Ctrl+u", as this can be used to great effect when you've mistyped a password, as an instant return to the beginning of the line, without having to worry about how many characters you've backspaced.
Output stdout and stderr to 2 different files
This is an interesting commands, using redirection and subshells to achieve a useful end:
command > >(tee stdout.log) 2> >(tee stderr.log >&2)
Another way to take screenshots from cli
This CLI idea has been submitted by reader James.
This method uses the scrot command, which is available on *buntu systems via apt, but may not be on your chosen distribution. The scrot command is a lot more powerful than the previous method, as it has far more relevant parameters. Here's an excerpt from its man page:
-b, --border
When selecting a window, grab wm border too
-c, --count
Display a countdown when used with delay.
-d, --delay NUM
Wait NUM seconds before taking a shot.
-e, --exec APP
Exec APP on the saved image.
-q, --quality NUM
Image quality (1-100) high value means high size, low compression.
Default: 75. (Effect differs depending on file format chosen).
-m, --multidisp
For multiple heads, grab shot from each and join them together.
-s, --select
Interactively select a window or rectangle with the mouse.
-u, --focused
Use the currently focused window.
-t, --thumb NUM
generate thumbnail too. NUM is the percentage of the original size
for the thumbnail to be.
-z, --silent
prevent beeping.
Its usage is fairly simple, in the format scrot [options] [file]. If the file parameter is left out, the format will be chosen as PNG, and the name will be the current Unix timestamp.
Variable text substitution
This CLI idea has also been submitted by reader James.
There's a simple way to exchange text within a variable, without piping it to sed or other process. It works as follows:
$ ls -1 *.jpg
1.jpg
2.jpg
3.jpg
4.jpg
$ for FILE in *.jpg; do echo ${FILE/jpg/gif}; done
1.gif
2.gif
3.gif
4.gif
As always, if anybody's got anything of interest to add, or any questions, just direct them to the comments!
n00b