Paul - The Programmer

simple & stupid

Detect CRLF (^M) line terminators in shell script

Shell will complain 'bad interpreter' error for script which contains CRLF (^M) line terminators. 

The error message likes 'bash: ./test.sh: /bin/bash^M: bad interpreter: No such file or directory'.

This generally caused by the script file was edited by a windows ( dos ) editor and saved with dos format.

How to check whether a shell script file contains CRLF?  Either the below tricks can help you out.

1) Grep the hex code of CR.

The new line terminator for a text on Unix system is only LF. So, the once the file contains CR, it's not a compatible unix shell script.

The hex code of CR is 0x0D. The grep command is :

grep -c $'\x0D' test.sh

-c means print the total number of match character.

To be honestly, I do not understand the $ in this command either. :P  I just found this black magic somewhere by Google.

--- update---

Quote from bash manual page:

Words of the form $'string' are treated specially. The word expands to
string, with backslash-escaped characters replaced as specified by the
ANSI C standard.

2) Find the hex code of CR by Perl Regular Expression.

The theory is the same to the above one. Just replace with Regular Expression. To be more precisely, Regular Expression match the whole CRLF in the end of each line.

perl -n -e 'print if /\x0d\x0a$/;' test.sh | wc -l

The hex code of LF is 0x0A. wc is to count all the matched lines.

3) Determin file's line teminator by file. This is my favorite one. :D

Command line tool file is used to check the file type of files. It also report the character set and line terminates of regular text file.

file -m /dev/null test.sh

-m /dev/null is a trick to force the file to treat shell script as a regular text file.

Good Linux Tool, find out the biggest file / directory in the system

No matter how big your hard disk is, it can still run out of space someday. So, do some regular cleaning up work is necessary. Free some space by deleting the files which are out of date or not needed anymore.

To get the space consumed by each directory with du and find out the biggest one with sort.

 

$du --max-depth=1 -h | sort -h -r

Meaning of du options:

--max-depth : print the total size of direcotries on the firest level.

-h  : print the size in human readable format (e.g.  1K, 2M, 3G, etc. ).

Meaning of sort options:

-h : sort human readable format numbers.

-r : reverse the result, the biggest number is on the top.

What I need to do is use this command recursively from the root directory ( / ) . It will finally lead me to the file or directory which consumes most of my storage.

Connect to wireless network with wireless tools

Wireless tools is a package of command line tools for configure wireless network.

With the help of wireless tools, it is no need to install the graphical network configuration tools, such as the wifi-radar.

The wireless tools consists with ifrename, iwconfig, iwgetid and iwlist.

To connect to a wireless network, we only need the help of iwlist.

iwlist can list all the nearby wireless nework access point and their addional information.

$ sudo iwlist ath0 scan 
ath0      Scan completed :
          Cell 01 - Address: 00:25:86:49:16:F4
                    ESSID:"TP-LINK_4916F4"
                    Mode:Master
                    Frequency:2.422 GHz (Channel 3)
                    Quality=21/70  Signal level=-74 dBm  Noise level=-95 dBm
                    Encryption key:on
                    Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 6 Mb/s
                              12 Mb/s; 24 Mb/s; 36 Mb/s; 9 Mb/s; 18 Mb/s
                              48 Mb/s; 54 Mb/s
                    Extra:bcn_int=100
                    Extra:ath_ie=xxxxxxxxxxxxxx

Now, we get the available access point. To access to the wireless network, we need to configure the network interface.

For Debian, the network interface configuration file is /etc/network/interfaces.

To use the interface ath0 to access the acccess point 'TP-LINK_4916F4', the configuration show like below:

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug ath0
iface ath0 inet dhcp
	# wireless-* options are implemented by the wireless-tools package
	wireless-mode managed
	wireless-essid TP-LINK_4916F4
	wireless-key1 s:xxxxxxxx

Connect to the wireless network by restarting the networking init script.

# /etc/init.d/networking restart

 

Why Google Chrome GPU acceleration does not work for me

The latest Google Chrome browser comes with the GPU accelereation feature.

You may already know that to enable the GPU acceleration, we only need to enable the flag 'GPU Accelerated Compositing' and flag 'GPU Accelerated Canvas 2D' in the tab about:flags.

But it is not that kind of easy. On Linux, the GPU acceleration needs the OpenGL 2.0 support.

By checking with glxinfo.

$ glxinfo | grep -i opengl
OpenGL vendor string: DRI R300 Project
OpenGL renderer string: Mesa DRI R300 (RV380 5460) 20090101 x86/MMX/SSE2 TCL
OpenGL version string: 1.5 Mesa 7.7.1
OpenGL extensions:

My video card only support OpenGL 1.5 so far. This means even though the flag is enabled in the Chrome, still no hardware accelerated for page rendering at all.

The ATI Catalyst driver can give you up to OpenGL 4.0 and better 3D performance. But for my old X300, I can only choose the open source drive xf86-video-ati with OpenGL support by Mesa 3D Graphic Library.

The Mesa 3D Graphic Library can support OpenGL 2.0 by software-only rendering driver. I doubt update Mesa library can bring any help. 

So, I just give up the Chrome GPU acceleration. 

By the way, the flag 'Web Page Prerendering' is really helpful to imporve the page loading performance.

Add prefix and append suffix to each line of text file

I need to update one text file to add prefix and suffix to each line. For instance, let's say the text file I need to update is like:

line-number-one
line-number-two
line-number-three

I want the file be updated as below.

prefix line-number-one suffix
prefix line-number-two suffix
prefix line-number-three suffix

Here are my solutions.

To update with vim:

:%s/.*/prefix & suffix/g

To update with sed:

$ sed 's/\(.*\)/prefix $1 suffix/' sample-file.txt

To update with awk:

$ awk '{ printf( "prefix %s suffix\n", $1 ); }' sample-file.txt