LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 11-25-2013, 11:20 AM   #1
ThreeNine
LQ Newbie
 
Registered: Nov 2013
Posts: 19

Rep: Reputation: Disabled
Shell script to mount and copy files


Hi all. New to the forum here. I'm working on building this boot CD that runs a shell script on startup. I have most of everything working very well, but there are a few sticking points I've run into.

So, first thing's first. One of the options in my script (I'm using the "read" "case" style to get answer from users) is to assume the system knows exactly where the hard drive is (/dev/sda1) and mount it. I would like the script to choose this option by default if no input is given in, say, 10 seconds. Haven't figured out how to do this yet.


The other question, is a bit more of a tricky one. OR at least I think it is. Secondary option needs to work on all hard drives. So what I need it to do is to mount all hard drives (automount should do, but I haven't tried it yet). Then, and this is where I'm having difficulties, it needs to copy a file from a known location on each hard drive to another location on the same drive. So for example, let's say I have two HDDs (ignoring the CD), I want it to:
Code:
#automount finds two drives, hda1 and hda2 and ignores the CD
cp /dev/hda1/path/file /dev/hda1/path2/file
cp /dev/hda2/path/file /dev/hda2/path2/file
#edit: actually should probably be more like /mnt/disk1 /mnt/disk2 etc etc
Well, I hope that makes sense. Let me know if you have any ideas.

Last edited by ThreeNine; 11-25-2013 at 11:24 AM.
 
Old 11-25-2013, 11:50 AM   #2
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394
Quote:
Originally Posted by ThreeNine View Post
So, first thing's first. One of the options in my script (I'm using the "read" "case" style to get answer from users) is to assume the system knows exactly where the hard drive is (/dev/sda1) and mount it. I would like the script to choose this option by default if no input is given in, say, 10 seconds. Haven't figured out how to do this yet.
Have a look at this:
Code:
#!/bin/bash

read -r -t 10 -p "Prompt the user to do something : " INPUT
[[ "$?" != "0" ]] && echo          # needed to force a carriage return if no input is given
INPUT=${INPUT:-"default_input"}    # set default if none is given

echo "--> $INPUT"
See the bash manual page:
- read command: SHELL BUILTIN COMMANDS --> read
- substitution: Parameter Expansion --> ${parameter:-word}

Quote:
The other question, is a bit more of a tricky one. OR at least I think it is. Secondary option needs to work on all hard drives. So what I need it to do is to mount all hard drives (automount should do, but I haven't tried it yet). Then, and this is where I'm having difficulties, it needs to copy a file from a known location on each hard drive to another location on the same drive. So for example, let's say I have two HDDs (ignoring the CD), I want it to:
Code:
#automount finds two drives, hda1 and hda2 and ignores the CD
cp /dev/hda1/path/file /dev/hda1/path2/file
cp /dev/hda2/path/file /dev/hda2/path2/file
#edit: actually should probably be more like /mnt/disk1 /mnt/disk2 etc etc
Not entirely sure what you want to do, but maybe this will help to get all mounted partitions:
Code:
df -P | awk '/^\/dev/ { print $6 }'
The output can be used in a for or while loop.

Last edited by druuna; 11-25-2013 at 11:51 AM.
 
1 members found this post helpful.
Old 11-25-2013, 12:02 PM   #3
ThreeNine
LQ Newbie
 
Registered: Nov 2013
Posts: 19

Original Poster
Rep: Reputation: Disabled
Thank you druuna. The first bit worked perfectly for me.

As for the df command, my output was:
/
/boot

Not sure if this was expected or not because the system I'm writing the script on only has 1 partition.
 
Old 11-25-2013, 12:12 PM   #4
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394
Quote:
Originally Posted by ThreeNine View Post
As for the df command, my output was:
/
/boot

Not sure if this was expected or not because the system I'm writing the script on only has 1 partition.
That is expected (kinda). If everything is mounted (why do you need to mount all hard drives??), the command given will show all mount points. If, for example, you plug in an USB stick and (auto) mount it the command will show one extra entry.

But, like I said before, I'm not sure what you want to do.
 
Old 11-25-2013, 12:20 PM   #5
ThreeNine
LQ Newbie
 
Registered: Nov 2013
Posts: 19

Original Poster
Rep: Reputation: Disabled
In my application, every hard drive will have a known file in a known path. So once we get to the drive it is a simple copy to a different location on the same drive. The simple method will work for most systems, but I want to make sure that this will work in case the system is a multi-drive or multi-boot.
 
Old 11-25-2013, 12:32 PM   #6
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394
Quote:
Originally Posted by ThreeNine View Post
In my application, every hard drive will have a known file in a known path. So once we get to the drive it is a simple copy to a different location on the same drive. The simple method will work for most systems, but I want to make sure that this will work in case the system is a multi-drive or multi-boot.
I don't know what you mean by multi-drive.

A system has one or more hard disks and every hard disk can have one or more partitions.

On a single OS (single-boot) system it is very probable that all those partitions are part of that OS.
On a multi boot system certain partitions belong to system X and others to Y (and maybe Z etc). The partitions belonging to one system are (in general) not mounted on the other systems.

If you want to write to partitions belonging to other systems you need to mount them first (you might add them to your /etc/fstab with the noauto option added to the default options). You do need to be careful when you do this; There is is chance that the uid's and gid's used are not the same on all the systems (user1 might have 1000/1000 on one system and 500/500 on the other).
 
Old 11-25-2013, 12:47 PM   #7
ThreeNine
LQ Newbie
 
Registered: Nov 2013
Posts: 19

Original Poster
Rep: Reputation: Disabled
Fair enough... so by multi-drive what I really meant is multiple hard disks. I could also be, in the most complicated case, that there could be multiple hard drives with multiple partitions on each. The script should simply print an error if it encounters a file system that is missing the file and move along to the next. It's not so much the mounting of the drives I'm struggling with, but feeding the list of drives into the commands I want to run, one after the other.

It may be that I'm wording things very poorly, in which case I apologize. Thank you for the help though
 
Old 11-25-2013, 01:27 PM   #8
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394
Maybe this will work for you: Find out which partitions from other systems need to be mounted and add these to /etc/fstab.

On one of my machines I can multi-boot into 4 different OS's. On the OS that I work on most I added the following in /etc/fstab:
Code:
# debian previous
/dev/sda6                         /mnt/Sda06      ext4   defaults,noauto,ro 0 0
# Red Hat 5.7
/dev/sda7                         /mnt/Sda07      ext4   defaults,noauto,ro 0 0
# Red Hat 6.4
/dev/sda8                         /mnt/Sda08      ext4   defaults,noauto,ro 0 0
# extra space for Red Hat 6.4
/dev/sda10                        /mnt/Sda10      ext4   defaults,noauto,ro 0 0
These four partitions aren't mounted when I start, the noauto options prevents this. I created 4 mount points (/mnt/Sda06 -> /mnt/Sda10) and can mount them at will.

I also included the ro option to make sure these partitions are mounted read-only.

After you mount these partitions and assuming the same mount points as shown in my example, you can do this (2 examples):
Code:
#!/bin/bash

checkFor="/path/to/file.to.check"

while read mPoint
do
  stat $mPoint$checkFor 1>/dev/null 2>&1
  [[ "$?" != "0" ]] && echo "File not found on : $mPoint$checkFor"
done < <(df -P | awk '/Sda[01][0-9]/ { print $6 }')

echo " -------"

for THIS_ENTRY in /mnt/Sda08 /mnt/Sda10
do
  stat $THIS_ENTRY$checkFor 1>/dev/null 2>&1
  if [[ "$?" != "0" ]] 
  then 
    echo "File not found on : $THIS_ENTRY$checkFor"
  fi
done
The first example automatically fetches all the /mnt/Sda* entries, the second one uses a static way of defining them.
Both use a different loop and the first one uses a very compact check instead of the longer if ... then .. fi used in the second one.
 
1 members found this post helpful.
Old 11-25-2013, 02:12 PM   #9
ThreeNine
LQ Newbie
 
Registered: Nov 2013
Posts: 19

Original Poster
Rep: Reputation: Disabled
Thanks druuna. That seems very promising. I will look at it closely and see if I can get it to work for me. I gave the first half a run, but the output was only -------- which is probably expected because nothing exists on /mnt/ for me? Full code gave me "File not found" for both Sda08 and Sda10. I was thinking that awk or sed might be the way to go.

I'm understanding this a little better. I think I can do something like:
cp $mPoint$checkFor $mPoint$moveto && echo "File not found"

etc etc...

I'll spend some time working with this.
 
Old 11-25-2013, 02:56 PM   #10
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394
Quote:
Originally Posted by ThreeNine View Post
I gave the first half a run, but the output was only -------- which is probably expected because nothing exists on /mnt/ for me?
Probably. Only you know what you did or did not do
Quote:
Full code gave me "File not found" for both Sda08 and Sda10.
The code snippet assumes that everything is mounted correctly. If the partitions are not mounted then it is obvious that the files cannot be found, which doesn't necessarily mean that they aren't there.
Quote:
I was thinking that awk or sed might be the way to go.

I'm understanding this a little better. I think I can do something like:
cp $mPoint$checkFor $mPoint$moveto && echo "File not found"

etc etc...

I'll spend some time working with this.
Have fun trying to get everything to work. If you get stuck; Just ask.....

About the:
Code:
cp $mPoint$checkFor $mPoint$moveto && echo "File not found"
the cp command might give unwanted output, do this to get rid of it:
Code:
cp $mPoint$checkFor $mPoint$moveto 2>/dev/null && echo "File not found"
BTW: You are now, again, talking about copying files so I'm going to warn, again: There is is chance that the uid's and gid's used are not the same on all the systems (user1 might have 1000/1000 on one system and 500/500 on the other). That is the reason why I mount those partitions read only, to prevent writing to them.
 
Old 11-25-2013, 09:29 PM   #11
ThreeNine
LQ Newbie
 
Registered: Nov 2013
Posts: 19

Original Poster
Rep: Reputation: Disabled
Alright, so I spent some time working with this, and haven't got it to work yet. So I found some questions to ask.

I understand what the
Quote:
df -P | awk '/Sda[01][0-9]/ { print $6 }'
line is doing, except for the [01][0-9] part. I'm not sure what this is supposed to be doing, so I can't be sure it's working. Also not sure how mPoint is getting set. If it's the < < just after done, then... ok if this is pointing back to the read command at the beginning of the while loop, what is causing the while loop to run for the first time? Or ever?

I feel like I'm getting very close to the point where I need to put this on a live USB and give it a run on a live system. Hopefully I can get that done tomorrow. The fact that my monitor at home started "hissing" and killing itself is part of why I've been testing this in an awkward way.

Thanks

Edit: Forgot to mention... uid and gid is not going to be a problem

Last edited by ThreeNine; 11-25-2013 at 09:38 PM.
 
Old 11-26-2013, 03:42 AM   #12
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394
Quote:
Originally Posted by ThreeNine View Post
I understand what the
Code:
df -P | awk '/Sda[01][0-9]/ { print $6 }'
line is doing, except for the [01][0-9] part. I'm not sure what this is supposed to be doing, so I can't be sure it's working.
The /Sda[01][0-9]/ part makes sure that only lines containing /Sda01 -> /Sda10 are targeted (all other lines are discarded). The [01][0-9] is a regular expression which means 0 or 1 (the [01] part) followed by 0 or 1 or 2 or .. or 9 (the [0-9] part).

If nothing is mounted on /mnt/SdaX then the above command will print nothing and if something is mounted on, say, /mnt/Sda05 then the output would be /mnt/Sda05.

Have a look here for more info about regular expressions: Regex Tutorial, Examples and Reference

Quote:
Also not sure how mPoint is getting set. If it's the < < just after done, then... ok if this is pointing back to the read command at the beginning of the while loop, what is causing the while loop to run for the first time? Or ever?
There are basically 2 ways to feed information to a while loop:
Code:
# method one
command | while read VARIABLE
do
  do_some_stuff_here
done

# or, method two
while read VARIABLE
do
  do_some_stuff_here
done < <( command )
The second one is preferred. In both cases bash looks at the whole thing and knows what to do.

Have a look here:
- Bash - While loop
- Loops and Branches (especially 11.1)
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] shell script to copy files into folder that matches the file name daveant Linux - Newbie 5 12-07-2011 08:28 AM
shell script to copy files eduard Linux - Newbie 9 07-13-2011 04:26 PM
SHELL SCRIPT to copy files from cdrom begin_learn Linux - Newbie 2 06-10-2009 09:10 PM
Shell Script to copy and number files extasic Programming 1 12-12-2008 07:29 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 09:24 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration