Showing posts with label Linux. Show all posts
Showing posts with label Linux. Show all posts

2014-01-10

Compilation of Ruby's Source Code on Ubuntu

Oliver's guide has listed the packages on which Ruby depends. Following strictly to the guide, you should start working with the programming language, instead of wasting time to read this article.
Goal: You need to compile Ruby for whatever reasons.
Background: You've read Oliver's guide. However, your goal does not match with those in Oliver's guide. Therefore, you don't need to do all the things in the guide and start to skim through the text and to scan for commands useful to you. (This is an essential skill to survive in *nix. [1])
Problem: You've found someuseful commands, and tried working out their dependencies. Nonetheless, you missed out some important commands and thus the dependencies were wrong. Unfortunately, you're unaware of such careless mistake and continued the process, before being stopped by the compiler's error message.
In this case, you found the following commands useful.
$ curl
# Substitute [version-number] with that of your downloaded archive.
# If you're NOT sure, use `ls' to list the files inside your folder.
$ tar -xvzf ruby-[version-number].tar.gz
$ cd ruby-[version-number]
$ make
Therefore, you ran all of these commands. Expecting to get things done and to proceed to the next step, you got an error message from the compiler.
Trial: Using a part of the compiler's error message as the query string a search engine, you get some other web pages on the same or similar topics. If you could find blog entries like this some, they might have links to other similar web pages, so you've got even more to read.
I've found DiStasio's article, which contains a hyperlink to Ladd's essay. I tried issuing the following commands accroding to the instructions there.
# Suppose that the current working directory is the same as the one in the above command list.
# If you're NOT sure, use `pwd' to check it.
$ cd ext/openssl
$ make
$ sudo make reinstall # I'd installed the wrong version of Ruby.
Lacking patience to read the blogs, knowledge of using makefiles and experience of compiling softwares from their source code, I don't know how to uninstall the wrong version of Ruby. Are there any make uninstall command?
I tried searching for reinstall and uninstall in the makefile, and failed to find any. Then, I realised that using search engines to answer my questions was inefficient. Reading the official manual of Make wouldn't be effective. Thus, without knowing the truth, I just try the last line of the above list of commands.
The make reinstall command successfully triggered a reinstallation of Ruby, but after running the command, I still received complaints form the compiler. Having no idea on the process, I did the same thing again: copied a part of the message and googled it, and ended up with further more pages to read. The amount of tab pages in my current browser window is too high and this stopped me from opening more web pages on Ruby compilation errors on Google's search result in a new tab.
It took me some time to find out that I overlooked the command below
$ sudo apt-get install build-essential zlib1g-dev libssl-dev libreadline-dev libyaml-dev libcurl4-openssl-dev curl git-core python-software-properties
In Oliver's guide, the above command is right aobve those commands for compiling and installing Ruby. Therefore, I installed them, and tried rebuilding Ruby by running make and sudo make reinstall in my ruby-[version-number]. (i.e. my Ruby source folder) It failed again. Without changing the current working directory directory in the above command list, I did the following because of Ladd's web page.
$ make
$ sudo make reinstall
But it failed again. Maybe I need to go back to ruby-[version-number], recompile the source code and reinstall Ruby again. So using the same current working directory as the one in the above command list, I did the following thing.
$ cd ../.. # For changing the current working directory to `ruby-[version-number]'.
$ make
$ sudo make reinstall
Things still went wrong! I remembered the make clean command, so without changing the current working directory, I ran the following commands.
$ make clean
$ make
$ sudo make reinstall
Remark: With the command dkpg -l | grep ruby, I realised that make clean doesn't uninstall Ruby. It just deletes all compiled files in ruby-[version-number].
It still wouldn't compile with the OpenSSL feature. However, some features that had failed to compile before I had run the command make clean could be compiled.
This inspired me to run the following commands.
$ cd ext/openssl
$ make clean
$ make
$ sudo make reinstall
However, I still got errors. There was a problem in getting the file ossl.o work. (I've forgotten the exact name of that file, and I couldn't find web pages about the same error.) I ignored the message and ran the following commands.
$ cd ../..
$ make clean
$ make
$ sudo make reinstall
But it still didn't go right. After running the commands make and make clean for a number of times, I eventually worked out a solution for my problem. Solution:
  1. Run the command make clean in both the ruby-[version-number] and ruby-[version-number]/ext/openssl directories.
  2. Run make in ruby-[version-number] to compile the source code.
    Some errors like "Failed to compile gdbm" will come out.
    It depends on your needs. Having no clue on what gdbm is, I just proceed to the reinstallation of Ruby.
  3. Run the command sudo make reinstall in ruby-[version-number].
    Then the command gem install bundle in Oliver's guide should work.
Lessons learnt:
  1. Always figure out the dependencies of a package.
  2. Be careful and patient while reading instructions on commands.
  3. Always clear all compiled files before any recompilation.

Reference:
[1]: http://user.frdm.info/ckhung/a/c013.php

2014-01-05

GNU ddrescue—A Powerful Data Recovery Tool

3 days ago, I encountered an error while moving a folder of about 3 GB from my USB stick to my hard disk using GUI. After 1.2 GB of the files are moved, the progress bar of the program just remained unchanged. I left the seat in front of my computer and did something else. Returning to the seat after half an hour, the situation had NOT been better. The displayed remaining time was still "unknown".
The I clicked the cancel button to stop the process, but it simply hangs. After terminating the process from the "System Monitor" (another GUI program), the read/write speed of the USB stick became extremely low. Instead of blinking frequently, the light bulb inside the USB stick went on and off slowing during a read/write operation.
In /var/log/syslog.1, it says
[  627.152020] usb 2-1: reset high-speed USB device number 4 using ehci_hcd
[  658.128020] usb 2-1: reset high-speed USB device number 4 using ehci_hcd
[  658.493165] sd 3:0:0:0: [sdf] Unhandled error code
[  658.493169] sd 3:0:0:0: [sdf]  Result: hostbyte=DID_ABORT driverbyte=DRIVER_OK
[  658.493174] sd 3:0:0:0: [sdf] CDB: Write(10): 2a 00 00 54 e9 30 00 00 01 00
[  658.493188] end_request: I/O error, dev sdf, sector 5564720
[  658.494531] quiet_error: 39 callbacks suppressed
[  658.494533] Buffer I/O error on device sdf1, logical block 5564658
[  658.495808] lost page write due to I/O error on sdf1
Oh! I need to recover the data! And I've found GNU ddrescue an excellent tool for the task. No expensive recovery plans are needed. Just ddrescue on a bootable media and some free space in a storage device will do.
It's important to note that the data recovery program should never be run on the damaged device. Otherwise, further damage will be done to the damaged device. [1] In addition, I don't recommend running the data rescue tool on the operating system(s) installed on your hard disk. The process takes a long time, so "patience is key". [1]
Booted into the command line interface (CLI) of Ubuntu Rescue Remix 12.04, I first formatted the D drive into an empty NTFS partition after backing up the data on that device. (i.e. /dev/sda5)
After that , I ran the following command: [1]
$ ddrescue -r1 -n -S -v /dev/sdxm /dev/sdyn [logfile]
# Substitute x with the appropriate partition letter of the source partition
# Substitute y with the appropriate partition letter of the destination partition
# Substitute m with the appropriate partition number of the source partition
# Substitute n with the appropriate partition number of the destination partition
The process is irreverisible so do it carefully.
In the screenshot below, x=f, y=a, m=1, n=5, and logfile=`backup1.log' .
But the program refused to work, so I have to --force it to work.

Captured using screendump.

The program read the blocks fast initially but it gradually slowed down. After running the command for over 20 hours, over 3700 MB of the data had been read. Although there's just about 400 MB to go, according to the average speed at that moment, it was an hour to recover 10 MB of the data. What's worse, the average speed was getting slower and slower! (Later, from GeekyProjects, I realised that the heat of the devices inhibits the process [2], and the logfile file feature enables users to pause the job. [3]) Therefore, always use a logfile. [4]
Without adequate knowledge on GNU ddrescue, I stopped the task with <C-c>, but it took the computer several minutes to receive this input. But what's next for an incomplete task? The files don't occupy the whole USB stick. It might took me another day if I waited for some while and then resumed the task. At that moment, I decided to try mounting the destination partition /dev/sdyn. Thinking that the destination was a NTFS partition from the partition table rendered by fdisk -l, I tried mount -t ntfs /dev/sdyn, but the computer wouldn't let me go. I was fortunate to be stopped by this error. Otherwise, I think I would do another harm to the file system. This time, I let mount to automatically decide the partition type by removing the -t flag. It worked! I could browse and open the file there. After that, I copied the files to a safe place (i.e. a normal data storage device) Finally, I've found that most of the files were salvaged, despite some corruption of the multi-media files.
Since then, I've really learnt a lesson: NOT to use GUI for copying big files, always use commands. Secondly, never use mv for big files, use cp instead.

Reference:
[1]: http://techmuck.blogspot.hk/2012/03/data-recovery-with-gnu-ddrescue.html
[2]: http://geekyprojects.com/storage/how-to-recover-data-even-when-hard-drive-is-damaged/
[3]: https://www.gnu.org/software/ddrescue/ddrescue.html
[4]: http://manpages.ubuntu.com/manpages/raring/man1/ddrescue.1.html

2013-12-29

Don't Kill a Fly with a Cannon—Console Creation of GIF Files

As the saying goes, a picture is worth a thousand words. Some netizens believe that if a picture tells the truth.
If you want to take a screenshot in Linux text mode, you may use fbgrab to get a PNG file (fbcat gives you a PPM file).
If you want to illustrate a process with a series of pictures, then you'll probably need a GIF file. GIMP provides an easy way of creating GIF files by selecting menu items and clicking a few buttons, but for geeks who are used to command line interfaces (CLI), this is not the final answer for them.
With reference to Unix & Linux Stack Exchange question 24014, if your source PNG files are named as [name]%s.png, then the right command is:
$ convert $(for ((a=0; a<700; a++)); do printf -- "-delay 10 [name]%s.png " $a; done;) [result].gif
# `-delay 10' means that each image is displayed for 0.1s.
# [name]: file name of the source PNG files without the ordinal number.
# `%s': the n-th PNG file.
# [result]: file name of the target GIF file.
Without the whitespace between png and the ending ", things won't work.
If the GIF animation has not been finished and intermediate files need to be saved, don't use the .gif format, use .miff instead. [1]

Reference:
[1]: http://www.imagemagick.org/Usage/anim_basics/#gif_anim