identify the usbflash drive in bash

Using applications, configuring, problems
Message
Author
User avatar
jrb
Posts: 1536
Joined: Tue 11 Dec 2007, 19:56
Location: Smithers, BC, Canada

identify the usbflash drive in bash

#1 Post by jrb »

In my ongoing struggle to learn bash scripting I have written a script file which when activated from a usbflash drive will substitute links into puppy podcast grabber (ppg) and download the podcasts to the usbflash drive.

Code: Select all

rm /usr/local/ppg/.done
rm /usr/local/ppg/serverlist.txt
rm /root/my-documents/Podcasts
ln -s /mnt/sdb1/ppg/.done /usr/local/ppg/.done
ln -s /mnt/sdb1/ppg/serverlist.txt /usr/local/ppg/serverlist.txt
ln -s /mnt/sdb1/Podcasts /root/my-documents/Podcasts
rxvt -title "Puppy Podcast Grabber" -sl 1000 -e "./ppg.sh"
It works fine as long as the usbdrive comes up as sdb1. I would like to have the script identify the name of the usbdrive and then use that for the symlinks. Any help will be appreciated.

Thanks, J

code_m
Posts: 65
Joined: Wed 02 Jul 2008, 19:11

#2 Post by code_m »

You can simply use a variable...

For example: /mnt/$DRIVE/
Instead of: /mnt/sdb1/

To define the variable you would export it and then run the script.

Lets say your drive comes up sdc2 and your script is name podcast2flash.sh... then you would:

Code: Select all

export $DRIVE=sdc2
./podcast2flash.sh
But you already knew the second one ;-)

it is also a good idea to use a test to remind you to set the variable if you forget... so your script should look like:

Code: Select all

rm /usr/local/ppg/.done
rm /usr/local/ppg/serverlist.txt
rm /root/my-documents/Podcasts

if [ -n "$DRIVE" ]
then
 ln -s /mnt/$DRIVE/ppg/.done /usr/local/ppg/.done
 ln -s /mnt/$DRIVE/ppg/serverlist.txt /usr/local/ppg/serverlist.txt
 ln -s /mnt/$DRIVE/Podcasts /root/my-documents/Podcasts
else
 echo Varible '$DRIVE' is not set
 echo Use export to set the varible
fi

rxvt -title "Puppy Podcast Grabber" -sl 1000 -e "./ppg.sh"
The test is rather simple.. if [ -n "$DRIVE" ] simply asks "if the variable $DRIVE is a non-zero length" then, continue running my commands, or else (has a zero lenth) tell me "this".

User avatar
erikson
Posts: 735
Joined: Wed 27 Feb 2008, 09:22
Location: Ghent, Belgium
Contact:

Re: identify the usbflash drive in bash

#3 Post by erikson »

jrb wrote:It works fine as long as the usbdrive comes up as sdb1. I would like to have the script identify the name of the usbdrive and then use that for the symlinks.
I assume that the script itself resides on the same usb partition and that you run it from there (if you navigate with ROX and click on the script to run it, pwd as used below is automatically correct).

Then in your script you can use...

Code: Select all

PWD=$(pwd)
MNTPNT=$(echo $PWD | cut -b1-9)
... and the contents of MNTPNT reflects the mountpoint.

Then you do

Code: Select all

ln -s $MNTPNT/ppg/.done /usr/local/ppg/.done
etcetera.

Example:

Code: Select all

# cd /mnt/sda6/puppOSfin
# PWD=$(pwd)
# MNTPNT=$(echo $PWD | cut -b1-9)
# echo $MNTPNT
/mnt/sda6
#
[size=84][i]If it ain't broke, don't fix it.[/i] --- erikson
hp/compaq nx9030 (1.6GHz/480MB/37.2GB), ADSL, Linksys wireless router
[url]http://www.desonville.net/[/url]
Puppy page: [url]http://www.desonville.net/en/joere.puppy.htm[/url][/size]

User avatar
jrb
Posts: 1536
Joined: Tue 11 Dec 2007, 19:56
Location: Smithers, BC, Canada

#4 Post by jrb »

Thanks for your reply code_m

I've tried to use export but this is what I get:

Code: Select all

# export $DRIVE=sda1
bash: export: `=sda1': not a valid identifier
When I look at export --help it tells me that "export [-nf] [name[=value] ...] or export -p"

code_m
Posts: 65
Joined: Wed 02 Jul 2008, 19:11

#5 Post by code_m »

Sorry about that...

I forgot that when setting a variable you do not type the "$" but instead is implied.

So use export DRIVE=sda1 or whatever label your drive is.

I never thought about using the idea of $PWD, that could work as well... but then the script has to be on your drive. Up to you I guess.

I will also do some investigating and see how ROX mounts save files (it would have the same "variable" issue). I may be able to write you an even better script...

User avatar
jrb
Posts: 1536
Joined: Tue 11 Dec 2007, 19:56
Location: Smithers, BC, Canada

#6 Post by jrb »

Thanks also erikson,

I tried your technique and it worked. Here is my code:

Code: Select all

PWD=$(pwd) 
MNTPNT=$(echo $PWD | cut -b1-9)

rm /usr/local/ppg/.done
rm /usr/local/ppg/serverlist.txt
rm -r /root/my-documents/Podcasts

ln -s $MNTPNT/ppg/.done /usr/local/ppg/.done
ln -s $MNTPNT/ppg/serverlist.txt /usr/local/ppg/serverlist.txt
ln -s $MNTPNT/Podcasts /root/my-documents/Podcasts

rxvt -title "Puppy Podcast Grabber" -sl 1000 -e "./ppg.sh"
After trying out a few commands I see that "pwd" gives the current path and "cut-b1-9" limits its length to nine characters.

Nicely done. Hopefully I'll remember and expand on this. :)

User avatar
jrb
Posts: 1536
Joined: Tue 11 Dec 2007, 19:56
Location: Smithers, BC, Canada

#7 Post by jrb »

No need to apologize code_m. I made that correction and your technique worked nicely.

My purpose with this is to learn bash scripting. I mean how hard is it to copy files from one location to another with Rox?

I've now used and learned 3 commands and how to set up variables. Besides there was an error in my code, I left the -r out of rm -r /root/my-documents/Podcasts. Tracking down errors should make it more memorable.

code_m
Posts: 65
Joined: Wed 02 Jul 2008, 19:11

#8 Post by code_m »

I did the same thing myself..

I wrote a script to mount a pup_save.2fs file. I learned later after I posted about that Puppy already had a script to do so. The only difference was that my script was meant to run from an unmounted drive.

Here was my first (and second to umount it) scripts:
http://www.murga-linux.com/puppy/viewtopic.php?t=33548

Although, I don't use the script that often... lol. I have learned recently that you can place scripts in a directory in the $PATH and you can use your script like any command. If you want to do this, you can't use the PWD directory because it's global. (I would put it in /usr/local/bin or /root/my-applications/bin)... It also works just as well to do a simple alias in .bashrc (but you already knew that!)

If you ever wanna chat, I hang out in #linuxcranks on irc.freenode.net a lot. I go by the same name. I find it fun to help "linux veterans" out when I happen to know something more (I've been using linux for about 4.5 months!).

User avatar
erikson
Posts: 735
Joined: Wed 27 Feb 2008, 09:22
Location: Ghent, Belgium
Contact:

#9 Post by erikson »

jrb wrote:My purpose with this is to learn bash scripting.
Great :-)

Then have a look at following code section, that you could put at the beginning of your script:

Code: Select all

MPNTS=$(grep /mnt /etc/mtab | cut -d' ' -f2)
for MNTPNT in $MPNTS
do
  if [ -d $MNTPNT/Podcasts ]; then
    OKAY=yes
    break
  fi
done
if [ '$OKAY' != 'yes' ]; then
  echo "Fatal error: no Podcasts directory found"
  exit
fi
Then you can place the script anywhere you like. If the loop exits successfully, MNTPNT contains the mountpoint of the (first) partition where a Podcasts directory was found and you can use it as in my previous post.
[size=84][i]If it ain't broke, don't fix it.[/i] --- erikson
hp/compaq nx9030 (1.6GHz/480MB/37.2GB), ADSL, Linksys wireless router
[url]http://www.desonville.net/[/url]
Puppy page: [url]http://www.desonville.net/en/joere.puppy.htm[/url][/size]

User avatar
jrb
Posts: 1536
Joined: Tue 11 Dec 2007, 19:56
Location: Smithers, BC, Canada

#10 Post by jrb »

OK Erikson, Hope you don't mind questions?

I placed your code at the beginning of mine but kept getting:
"Fatal error: no Podcasts directory found"
So I investigated "grep" and "cut" and made a few changes. grep searchs for the phrase "/mnt" in /etc/mtab. I changed it to "/mnt/s" because I was also getting /initrd/mnt/tmpfs as well as /mnt/sde1. I had to reverse the -d" " and -f2 options with cut.

With:

Code: Select all

MNTPNT=$(grep /mnt/s /etc/mtab | cut -f2 -d' ') 

rm /usr/local/ppg/.done
rm /usr/local/ppg/serverlist.txt
rm -r /root/my-documents/Podcasts

ln -s $MNTPNT/ppg/.done /usr/local/ppg/.done
ln -s $MNTPNT/ppg/serverlist.txt /usr/local/ppg/serverlist.txt
ln -s $MNTPNT/Podcasts /root/my-documents/Podcasts

rxvt -title "Puppy Podcast Grabber" -sl 1000 -e /usr/local/ppg/ppg.sh
I can get it to work anywhere with any flashdrive name.

I understand that you put in the "if" statements to return an error message if the proper drive cannot be found but I have not been able to follow this procedure and I can't get it to work. :(

Could you walk me through it?

User avatar
erikson
Posts: 735
Joined: Wed 27 Feb 2008, 09:22
Location: Ghent, Belgium
Contact:

#11 Post by erikson »

jrb wrote:OK Erikson, Hope you don't mind questions?
Of course not.

Actually my code was flawed, bash scripting is often forgiving and indifferent on type of quotes, but sometimes *not*. '$OKAY' (with single quotes) is not the contents of variable OKAY (as I intended) but the string $OKAY which is obviously never equal to the string yes - so the test should read [ "$OKAY" != "yes" ] with double quotes around $OKAY. The quotes around yes may be single or double, or may even be dropped, doesn't matter.

The code then reads:

Code: Select all

MPNTS=$(grep ' /mnt' /etc/mtab | cut -d' ' -f2)
for MNTPNT in $MPNTS
do
  if [ -d $MNTPNT/Podcasts ]; then
    OKAY=yes
    break
  fi
done
if [ "$OKAY" != "yes" ]; then
  echo "Fatal error: no Podcasts directory found"
  exit
fi
One might be inclined to drop the quotes altogether, but the variable OKAY is not initialised when no Podcasts directory is found and a test on $OKAY without the double quotes doesn't like that.

As an alternative to your /mnt/s method to exclude the tmps mount (which is okay), I now grep on ' /mnt' (with a space before /), in order to exclude /initrd mounts.
I had to reverse the -d" " and -f2 options with cut.
Strange... it ought to work both ways, and indeed it does for me when I test it (on Puppy 3.01).
[size=84][i]If it ain't broke, don't fix it.[/i] --- erikson
hp/compaq nx9030 (1.6GHz/480MB/37.2GB), ADSL, Linksys wireless router
[url]http://www.desonville.net/[/url]
Puppy page: [url]http://www.desonville.net/en/joere.puppy.htm[/url][/size]

User avatar
jrb
Posts: 1536
Joined: Tue 11 Dec 2007, 19:56
Location: Smithers, BC, Canada

I think I understand - yay!

#12 Post by jrb »

Erikson, I believe I've got it. Your revised code worked beautifully. Forgive my earlier "corrections." :oops: I was looking for the problem without enough understanding. I have taken your latest code and changed it a bit, partly to increase understanding and partly to tailor to my needs. Here is what I presently have:

Code: Select all

MPNTS=$(grep ' /mnt' /etc/mtab | cut -d' ' -f2) 
for MNTPNT in $MPNTS 
do 
  if [ -a $MNTPNT/ppg/.done ]; then 
    OKAY=yes
    echo "Good" 
    break 
  fi 
done 
if [ "$OKAY" != "yes" ]; then 
  echo "Fatal error: files not found" 
  exit 
fi

rm /usr/local/ppg/.done
rm /usr/local/ppg/serverlist.txt
rm -r /root/my-documents/Podcasts

ln -s $MNTPNT/ppg/.done /usr/local/ppg/.done
ln -s $MNTPNT/ppg/serverlist.txt /usr/local/ppg/serverlist.txt
ln -s $MNTPNT/Podcasts /root/my-documents/Podcasts

rxvt -title "Puppy Podcast Grabber" -sl 1000 -e /usr/local/ppg/ppg.sh
Thanks for your help. I believe this initial understanding of "grep" and "if" will make understanding the script files in Puppy much easier. 8)

code_m
Posts: 65
Joined: Wed 02 Jul 2008, 19:11

#13 Post by code_m »

If you go about changing any of Puppy's default scripts make sure to back them up first obviously. I prefer to tar -cvzf the back up, so then you only need to extract if you want to restore, no need to create an extra directory or anything funny like that.

Just a note for bash: like any language you want to avoid an "Unconditional loop" where two if statements try to do opposing tasks. Not a major concern unless your actually working with loops, but still can cause a lot of headaches.

A simple loop you hear a lot in conversation I'll do it if you do it ... bet you never thought you talked in bash now did you?

Bruce B

#14 Post by Bruce B »

Looks complicated to me.

The mount point should be the same regardless of how Linux sees the device.

The only thing left is locating device so, it can be mounted. The way I did it before, in this forum, as I remember is fdisk -l, look for something unique about that device. Example:

Code: Select all

/dev/hda1   *           1        7557     3808696+  83  Linux
/dev/hda2            7558        8126      286776   82  Linux swap / 
/dev/hdb1   *           1         732     5879758+  83  Linux
/dev/hdb2             733         764      257040   83  Linux
/dev/hdc1   *           1        1772     3905968+  83  Linux
/dev/hdc2            1772        3102     2931862+  83  Linux
/dev/hdd1   *           1        4063     2047720+  83  Linux
Every line has something unique for search criteria. Even if hdc1 floats around, for example, I could find how it's identified by fdisk -l | grep 3905968

I think one fairly simple line is all you need to locate your device location and put it in a variable.

The second command would mount it on your constant mount point.

I don't see off hand, a reason for more than two simple lines to do the job.

User avatar
erikson
Posts: 735
Joined: Wed 27 Feb 2008, 09:22
Location: Ghent, Belgium
Contact:

#15 Post by erikson »

Bruce B wrote:Looks complicated to me.
Sure, but it was a good opportunity to introduce some bash techniques to jrb :-)

My usb hdd is /dev/sda with kernel 2.6.21.7 (e.g. Puppy 3.01) and /dev/sdb with kernel 2.6.25.16 (e.g. Puppy 4.1). My usb stick may be /dev/sda or /dev/sdb or /dev/sdc depending on kernel and on what's attached. I find the devices as follows:

Code: Select all

# probedisk
/dev/sda|Direct-Access|Seagate FreeAgentDesktop
/dev/sdb|Direct-Access|SanDisk U3 Cruzer Micro 
/dev/hda|disk|ST94019A
/dev/hdc|cdrom|PHILIPS CD-RW/DVD-ROM CDD5263
#
# probedisk | grep Sea | cut -b1-8
/dev/sda
#
# probedisk | grep San | cut -b1-8
/dev/sdb
#
# SANDRV=$(probedisk | grep San | cut -b1-8)
# echo $SANDRV
/dev/sdb
[size=84][i]If it ain't broke, don't fix it.[/i] --- erikson
hp/compaq nx9030 (1.6GHz/480MB/37.2GB), ADSL, Linksys wireless router
[url]http://www.desonville.net/[/url]
Puppy page: [url]http://www.desonville.net/en/joere.puppy.htm[/url][/size]

User avatar
erikson
Posts: 735
Joined: Wed 27 Feb 2008, 09:22
Location: Ghent, Belgium
Contact:

#16 Post by erikson »

Maybe Bruce could comment or improve...

In my bash scripts, I'm now getting mount points of partitions on my ush hdd (Seagate) using a function that either finds the existing mount point, or, (if not yet mounted) mounts the partition. If several mount points exist for the partition, the first one is used. I have a similar function fmppen for my pendrive (using grep "SanDisk").

It's also an illustration of the use of array variables in bash.

Code: Select all

# Function: get mount point of partition "$1" on usb hdd
# if not yet mounted, mount it
fmphdx() {
 HDX=$(probedisk | grep "Seagate" | cut -b6-8)
 MPHDX[$1]=$(mount | grep "/dev/$HDX$1" | head -n 1 | cut -d' ' -f3)
 if [ ! ${MPHDX[$1]} ]; then
  MPHDX[$1]="/mnt/$HDX$1"
  mkdir -p ${MPHDX[$1]}
  mount /dev/$HDX$1 ${MPHDX[$1]}
 fi
}
The function is called as follows (e.g. for partitions 6 and 9):

Code: Select all

fmphdx 6
fmphdx 9
The mount points can be used as follows:

Code: Select all

cd ${MPHDX[9]}
cat ${MPHDX[6]}/boot/grub/menu.lst
... etcetera
[size=84][i]If it ain't broke, don't fix it.[/i] --- erikson
hp/compaq nx9030 (1.6GHz/480MB/37.2GB), ADSL, Linksys wireless router
[url]http://www.desonville.net/[/url]
Puppy page: [url]http://www.desonville.net/en/joere.puppy.htm[/url][/size]

amigo
Posts: 2629
Joined: Mon 02 Apr 2007, 06:52

#17 Post by amigo »

You can use 'stat' to find out which drive you are on or you might use the mountpoint program.

Bruce B

#18 Post by Bruce B »

erikson wrote:Maybe Bruce could comment or improve...
An explanation is in order. About me and my skill levels.

Dad was recruited as a computer scientist in mid fifties. At that time weren't much in the way of computers, or training on the subject. At that time the government and contractors used highly educated mathematicians as people for programming.

The computer was not powerful by todays standards, but it used so much power it took several minutes, something like a half an hour to turn on. The reason why is, if they turned it on all at once it would knock down the city's power plant.

Computers evolved and so did dad's skill. There were periods and circumstances where he had to write programs with just several kilobytes of memory.

This was an era when a programmer not only had to produce a finished product, he had to do with with extremely tight and efficient code on many occasions.

Later, he taught me C, I'd write a nice trivial and show it to him. He would lovingly show me a way to do the same thing using a lot less code. I marveled at the genius in simplicity and learned to respect it very much.

Programming was a hobby for me. As it worked out I dropped C and became a 'serial' MS-DOS batch programmer. I became what I think is a master batch programmer. It seems is if there was little I couldn't do with the command.com and some well designed external utilities.

Later I learned Unix. An almost unheard of Unix by Intel for x486. No X, very basic Unix and it was all CLI.

When it comes to bash scripting, I'm not very experienced at all, by my own opinion. Just interested and learning.

Sometimes I go over my bash scripts and improve them, try and make them better and sometimes think of ways to do the same with less.

That's all, just so you don't think me expert in an area I'm not.

Bruce

Bruce B

#19 Post by Bruce B »

A two liner

Code: Select all

#!/bin/sh

# suppose hdc1 floats, (which is doesn't), but for purpose of example that's 

# OK

# Never knowing how it's identified, I find it using a unique string from

# fdisk output which is 3905968

# if I use the long form --characters, instead of -c , the code is easier 
# for all to read

CRAZY_PART=`fdisk -l | grep 3905968 | cut --characters=1-9`
mount -t ext2 $CRAZY_PART /foo

# is it mounted ?

grep foo /etc/mtab

User avatar
jrb
Posts: 1536
Joined: Tue 11 Dec 2007, 19:56
Location: Smithers, BC, Canada

#20 Post by jrb »

I have to say I'm getting way more than I hoped for out of this topic. :D Although I haven't had time to go through all this homework. Just had to let you know I did an adaptation of Erik's first code and applied it to a simple usbflash to usbflash backup script that I had been using. (Which I had 4 different versions of depending on what the usbflash's were called).

Code: Select all

MPNTS=$(grep ' /mnt' /etc/mtab | cut -d' ' -f2) 
for MNTPNT in $MPNTS 
do 
  if [ -a $MNTPNT/00usb1 ]; then 
    OKAY=yes
    echo "Good" 
    break 
  fi 
done 
MPNTS2=$(grep ' /mnt' /etc/mtab | cut -d' ' -f2) 
for MNTPNT2 in $MPNTS2 
do 
  if [ -a $MNTPNT2/00usb2 ]; then 
    OKAY2=yes
    echo "Good" 
    break 
  fi 
done 
if [ "$OKAY" != "yes" ]; then 
  echo "Fatal error: files not found" 
  exit 
fi
if [ "$OKAY2" != "yes" ]; then 
  echo "Fatal error: files not found" 
  exit 
fi
cp -Ruv $MNTPNT/NWCC $MNTPNT2
I just created a file on each flashdrive, 00usb1 and 00usb2 and then let "if" check for them. Works great!!! Backs up my latest files instantly.

Post Reply