Cleaning a virus that makes the whole removable disk read-only.

Once before, I’ve encountered a virus that transfers the entire contents of the usb removable disk to a folder with a blank filename, and then creates a self-running link in the root directory that copies the virus to the hard disk, so that it propogates itself to any new removable disk that is connected. But this was a new breed that made the removable usb drive read-only, so much so that most except the most hard core linux utilities would fail to fix it. A friend had handed the disk over to me, requesting me to see if my “linux PC can fix it”.

The command which fixed the write protect status was:

sudo blockdev --setrw /dev/sdc1

This allowed me to remount it as read-write:

sudo mount -o rw,remount /dev/sdc1 /home/joel/usb

so that I could finally run clamscan and fix it:

clamscan --remove /home/joel/usb

To rename the folder with a blank space as name, I simply used:

mv '/home/joel/usb/ ' /home/joel/usb/ab

You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

Generating a list of virtualmin public folders for backup

The following perl script creates this at /root/bash-advanced-scripts/backupqueue.lst

#!/usr/bin/perl
my $filename = '/root/bash-advanced-scripts/backupqueue.lst';
open(my $fh, '>', $filename) or die "Could not open file '$filename' $!";
my @files = </etc/webmin/virtual-server/domains/*>;
foreach my $file (@files) {
    open   (FILE, "$file");
    while(my $line= <FILE> ){
        if ($line =~ /(^public_html_path=)(.*)/) {
            print "$2\n";
            print $fh "$2\n";
        }
    }
    close FILE;
}
close $fh;
print "Wrote to  $filename.\n";

You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

Add desktop launcher for wine application on Ubuntu

Here’s a sample for fastone image viewer:

#!/usr/bin/env xdg-open
[Desktop Entry]
Name=FSViewer
GenericName=FS Viewer
Comment=Sync your files across computers and to the web
Exec=wine "E:\Software\Graphics Utils\Image Viewers\FSViewer55\FSViewer.exe"
Terminal=false
Type=Application
Icon=/home/joel/fsviewer.ico
Categories=Network;FileTransfer;
StartupNotify=false

First copy your desired application’s icon from the /usr/share/applications directory to Desktop,

sudo cp /usr/share/applications/filename.desktop ~/Desktop

Then change the permissions(give execute permission to the .desktop file) of copied .desktop file on the Desktop,

sudo chmod +x ~/Desktop/filename.desktop

Double click on the application icon to run it’s corresponding application.


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

Managing printers from the command line

Get a list of printers:

# lpstat -p -d
printer DCP7060D is idle.  enabled since Sunday 27 September 2015 11:13:03 PM IST
printer RICOH-SP-111-DDST is idle.  enabled since Sunday 27 September 2015 10:18:49 PM IST
system default destination: RICOH-SP-111-DDST

Print to a specific printer:

lp -d printer filename

Example:

# lp -d DCP7060D moddriver.txt
request id is DCP7060D-1 (1 file(s))

Set a default printer:

lpoptions -d printer

You can get a complete list of options from the help available on localhost


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

How to recover auto save file in emacs?

While opening a file which you were editing earlier, you might see the message prompting that auto-save data is available, and whether you wish to recover it. If you wish to do that,

Type:
Alt-X
recover-file
Press Enter

Now you will be prompted for filename. Enter it.
Confirm that you wish to recover autosave data.
You may sometimes be asked:

...htdocs/user/config.php locked by [email protected].. (pid 18467): (s, q, p, ?)?

You have the following options:
sSteal the lock. Whoever was already changing the file loses the lock, and you gain the lock.
pProceed. Go ahead and edit the file despite its being locked by someone else.
qQuit. This causes an error (file-locked), and the buffer contents remain unchanged–the modification you were trying to make does not actually take place.


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

Linux find command cheatsheet

Generic Syntax:

find [path] -[option1] [argument to option1] -[option2] [argument to option2]

etc

Multiple options can be combined by specifying them one after the other

Find by filename

find . -iname [filespec]

-iname: Case insensitive name search

-name: Case sensitive

Find and delete file:

find . -iname [filespec] -delete

There are three ways to delete found files:

  •  -delete option
    • find /path/to/search -delete[/code]
      
  • Using xargs:
    • find /path/to/search | xargs rm[/code]
      
  • With exec
    • find /path/to/search -exec {} \;[/code]
      
Find only in current directory (Specify level of search): find . -iname [filespec] -maxdepth [level] level1: Only in current dir  Find only files/directories: By default, both files and directories are searched. You can specify one or the other with: -type f : Only files -type d: Only directories Find files more than a specific file size, and display its size:
find . -size +200M -exec du -h {} \;

where I have asked it to find all files more than 200MB in size and display sizes. I get a result like this:

351M    ./X-Files-Season1-HQ-DVDRIP-624x464/DISC 4/01.14.13- Gender Bender (21-01-1994)/01.14.13- Gender Bender (21-01-1994).avi
351M    ./X-Files-Season1-HQ-DVDRIP-624x464/DISC 4/01.16.15- Young at Heart (11-02-1994)/01.16.15- Young at Heart (11-02-1994).avi
351M    ./X-Files-Season1-HQ-DVDRIP-624x464/DISC 5/01.19.18- Shapes (01-04-1994)/01.19.18- Shapes (01-04-1994).avi
351M    ./X-Files-Season1-HQ-DVDRIP-624x464/DISC 5/01.18.17- Miracle Man (18-03-1994)/01.18.17- Miracle Man (18-03-1994).avi
351M    ./X-Files-Season1-HQ-DVDRIP-624x464/DISC 5/01.17.16- E.B.E. (18-02-1994)/01.17.16- E.B.E. (18-02-1994).avi
351M    ./X-Files-Season1-HQ-DVDRIP-624x464/DISC 5/01.20.19- Darkness Falls (15-04-1994)/01.20.19- Darkness Falls (15-04-1994).avi

Here, note that I have actually passed on the file name to du, which is responsible for the resulting listing.

Note notes from man on time related options:

-mmin n
File's data was last modified n minutes ago.

-mtime n
File's data was last modified n*24 hours ago. See the comments for -atime to understand how rounding affects the interpretation of file modification
times.

Notes on the exec option:

 -exec command ;

All following arguments to find are taken to be arguments to the command until an argument consisting of `;' is encountered. The string `{}' is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find. Both of these constructions might need to be escaped (with a `\') or quoted to protect them from expansion by the shell.

Note that there is something similiar to exec: the -ok option

It works just like -exec, except that -ok asks user confirmation before running the command. See below:

[[email protected]] /var/www/virtual/joel.co.in/htdocs/downloaded #find . -size +200M -ok du -h {} \;
&lt; du ... ./X-Files-Season1-HQ-DVDRIP-624x464/DISC 4/01.15.14- Lazarus (04-02-1994)/01.15.14- Lazarus (04-02-1994).avi &gt; ? n
&lt; du ... ./X-Files-Season1-HQ-DVDRIP-624x464/DISC 4/01.13.12- Beyond the Sea (07-01-1994)/01.13.12- Beyond the Sea (07-01-1994).avi &gt; ? y
5.4M    ./X-Files-Season1-HQ-DVDRIP-624x464/DISC 4/01.13.12- Beyond the Sea (07-01-1994)/01.13.12- Beyond the Sea (07-01-1994).avi
&lt; du ... ./X-Files-Season1-HQ-DVDRIP-624x464/DISC 4/01.14.13- Gender Bender (21-01-1994)/01.14.13- Gender Bender (21-01-1994).avi &gt; ? y
351M    ./X-Files-Season1-HQ-DVDRIP-624x464/DISC 4/01.14.13- Gender Bender (21-01-1994)/01.14.13- Gender Bender (21-01-1994).avi
&lt; du ... ./X-Files-Season1-HQ-DVDRIP-624x464/DISC 4/01.16.15- Young at Heart (11-02-1994)/01.16.15- Young at Heart (11-02-1994).avi &gt; ?

File details, with printf:

The printf option accepts a multitude of options and can provide lots of useful info.

Eg: I'm printing the filename and the size in bytes:

$find . -size +200M -printf "%f %s\n"
01.15.14- Lazarus (04-02-1994).avi 367159296
01.13.12- Beyond the Sea (07-01-1994).avi 361488384
01.14.13- Gender Bender (21-01-1994).avi 367157248
01.16.15- Young at Heart (11-02-1994).avi 367153152
01.19.18- Shapes (01-04-1994).avi 367165440
01.18.17- Miracle Man (18-03-1994).avi 367159296
01.17.16- E.B.E. (18-02-1994).avi 367167488
01.20.19- Darkness Falls (15-04-1994).avi 367171584
01.02.01- Deep Throat (17-09-1993).avi 367187968
01.01.79- Pilot (10-09-1993).avi 367173632
01.24.23- The Erlenmeyer Flask (13-05-1994).avi 367163392
01.23.22- Roland (06-05-1994).avi 367169536
01.22.21- Born Again (29-04-1994).avi 367222784
01.21.20- Tooms (22-04-1994).avi 367163392

Note that all arguments to go with print need to be quoted.


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

Parse text files with assignments, and get the value – Bash

Suppose you have a text file containing the following:

strings=hello world

and you wanted to use the value of strings, which is “hello world” in your script

You can parse it with the following:

grep '^strings=' test | sed 's/strings=//g'

So the generic format is:

grep '^variablename=' filename | sed 's/variablename=//g'

The grep searches for a string beginning with ‘strings=’, in the file ‘test’, and outputs the following:

$grep '^strings=' test
strings=hello world

Next we have to remove the initial assignment part upto and including the ‘=’ sign, this is done by piping the output of grep, to sed.

Now the sed line substitutes the string “strings=” with an empty string. The substitution is done globally. Finally sed outputs just the value of the assigned variable.

Practical example:

I wanted to use the main User directory on the server, to make my backups more generic. I know that the file /etc/imscp/imscp.conf contains the following line:

USER_HOME_DIR = /var/www/virtual

So what I want is to get /var/www/virtual from this file, removing the assignment and spaces.

The solution is:

grep -i 'USER_HOME_DIR' imscp/imscp.conf | sed 's/USER_HOME_DIR[ ]=[ ]//'

which outputs:

/var/www/virtual

without the initial spaces. A space within a square brackets matches any number of spaces in the expression.

However, if you want to use these values in variables, you need to make minor adjustments to take care of variable escaping:

apache_home_var="USER_HOME_DIR"
apache_conf_file=/etc/imscp/imscp.conf
grep -i "$apache_home_var" "$apache_conf_file" | sed 's/'$apache_home_var'[ ]=[ ]//'

 


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

Automating server backup downloads

The first thing needed is the ftp script:

#!/bin/bash
ftp -in ftp.hostname.com &lt;&lt; SCRIPTEND
user [email protected] ftppassword
binary
cd /backups
mget filename.tar.bz2
SCRIPTEND
./alertmail

The next one is the email alert that is sent automatically when the task is over:

$cat alertmail
#!/bin/bash
echo "This is the server at joel.co.in. Your file has been downloaded!" | mail -s "FTP task done" "[email protected]"[

 

The next is a script that invokes nohup to prevent the task from terminating when the shell terminates:

cat dontcancel
#!/bin/bash
nohup $1

An ampersand may be inserted at the end to keep the process in the background.


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

Batch Remove spaces from filenames, and convert upper case to lowercase via bash

Use the following script:

#!/bin/bash

ls | while read -r FILE
do
    mv -v "$FILE" `echo $FILE | tr ' ' '_' | tr -d '[{}(),\!]' | tr -d "\'" | tr '[A-Z]' '[a-z]' | sed 's/_-_/_/g'`
done

 


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.

Bash script for splitting a filename, extension and path from fullpath

Call the function split_filenames with the first argument as the full filename with path. Alternately, set the variable fullfile to this value.

#!/bin/bash

split_filenames() {
# echo "Called with Arg: $1"
if [ ! "$1" = "" ]
then
fullfile=$1

fi
# echo I got this filename for processing $fullfile
filename=$(basename "$fullfile")
fname=$(basename "$fullfile")
nameonly=${filename%.*}
ext=${fname##*.}

echo "filename $filename"

filename=${fullfile%.*}
pathonly=${fullfile%/*}

if [ "$pathonly" = "$fullfile" ]
then
pathonly="$pat"
fi

echo "Path $pathonly"
echo "Name $nameonly"

chkper=$(echo $fullfile | grep -c "\.")
# echo "Number of periods:$chkper"

if [ ! "$chkper" = "0" ]
then
echo "Extension $ext"
else
echo "No extension"
fi

#out_file=$pathonly/$nameonly"_signed."$ext

}

for i in ~/Dropbox/SSH\ Keys/*
do
echo
echo Path and Name: $i
split_filenames "$i"
#cp "$i" testssh/
done[/code]
In the example, the main event calls the function from a loop which cycles through all the files in the specified directory.


You are reading this post on Joel G Mathew’s tech blog. Joel's personal blog is the Eyrie, hosted here.