5

I need to mount a volume, tar the contents of the mounted volume and unmount that mounted volume, in a single shell script.

So I coded as,

$ cat sample.sh
sudo mount -o loop Sample.iso /tmp/mnt
cd /tmp/mnt
tar-cvf /tmp/sample.tar *
sudo umount /tmp/mnt

I got the error umount: /tmp/mnt: device is busy.

So I checked the

$ lsof /tmp/mnt

It outputs the current "sh" file. So I convinced myself, /tmp/mnt is busy in the current script (in this case, sample.sh).

Is there any way around for (mount, tar, unmount) in the same script ?

P.S : I'm able to unmount the /tmp/mnt volume once the script finishes.

15

You need to exit the directory to unmount it, like this:

#!/bin/bash
sudo mount -o loop Sample.iso /tmp/mnt
cd /tmp/mnt
tar -cvf /tmp/sample.tar *
#Got to the old working directory. **NOTE**: OLDPWD is set automatically.
cd $OLDPWD
#Now we're able to unmount it. 
sudo umount /tmp/mnt

That is it.

  • I'm not sure how portable this is, but in bash you can use - as an alias of $OLDPWD in cd : cd - will bring you back to the previous dir. – Aaron Jan 20 '17 at 15:16
  • 1
    Or just cd /. Since the script then exits, it doesn't really matter which directory you change to, as long as it isn't /tmp/mnt. – Thomas Padron-McCarthy Jan 20 '17 at 17:14
  • 2
    There's no reason to use $OLDPWD or cd - or anything like that. Just cd /. The cd invocation only affects the subshell the script is running in, and all we need is to leave /tmp/mnt. Any target will do since, once the script exits, we will always be in whatever directory we were in when the script was launched. – terdon Jan 20 '17 at 18:51
  • @ThomasPadron-McCarthy and @terdon Just in case there were some ill effects, I wouldn't want to cd / and potentially do something in /. Instead, I'd cd /tmp – Monty Harder Jan 20 '17 at 20:02
  • 4
    @LucianoAndressMartini The easiest way to do that is provided by @Kusalananda: ( cd /tmp/mnt && tar -cvf /tmp/sample.tar * ) No explicit cd required because the subshell terminates as soon as the tar command exits. To be clear, I'm not arguing that cd /tmp is superior to returning whence it came; I'm only objecting to cd / as a bad practice. – Monty Harder Jan 20 '17 at 21:23
11

The device is "busy" since you just used cd to move into it. You can not unmount the partition of the current working directory (of any process, in this case the shell).

Your script:

sudo mount -o loop Sample.iso /tmp/mnt
cd /tmp/mnt
tar -cvf /tmp/sample.tar *
sudo umount /tmp/mnt

Modified script without the same issue:

sudo mount -o loop Sample.iso /tmp/mnt
( cd /tmp/mnt && tar -cvf /tmp/sample.tar * )
sudo umount /tmp/mnt

Since the cd happens in a sub-shell, it will not affect the environment outside of it, and the current directory at the time of the umount will be wherever you were when you executed the script.

This is a very common shell construct, i.e. to do

( cd dir && somecommand )

It is a lot cleaner (and clearer) than trying to cd somewhere and then back again, especially when having to go into multiple directories during the course of one script.

With the && it also means that the command won't be executed if the cd for some reason failed. In your script, if the mount failed, you would still create a tar archive of an empty (?) directory, for example, which may not be what you would want.

A shorter variant that makes use of the -C flag of tar:

sudo mount -o loop Sample.iso /tmp/mnt
tar -cvf /tmp/sample.tar -C /tmp/mnt .
sudo umount /tmp/mnt

This makes tar do the cd internally before adding the current directory (/tmp/mnt) to the archive. Notice, though, that this has the effect that hidden files or folders will also be added to the archive.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.