bash script to chroot

Programming languages, Coding, executables, and scripting.
Post Reply
Message
Author
User avatar
nadir
Posts: 5964
Joined: 2009-10-05 22:06
Location: away

bash script to chroot

#1 Post by nadir »

I often need to chroot to repair grub or do whatever.
I got a bit of tired to do:
mkdir /media/disk
mount /dev/sdXXX /media/disk
mount -o bind dev /media/disk/dev
mount -t proc /proc /media/disk/proc
mount -o bind sys /media/disk/sys
chroot
exit
umount /media/disk/{sys,proc,dev}
umount /media/disk
Especially if repairing grub fails and i do it lots of times in a row.

I made a scipt to do that (like usually with the stuff i am learning at the moment, not the best tools perhaps).
Have a look at it if you like and let me know what you think
(i made some tests and ran it three times in real life. From what i see it seems to work)
pastebin with highlighting; or here:

Code: Select all

#!/usr/bin/env bash

set -e 
clear; date
echo 

############
# Variables
############

MOUNT_POINT="/media/disk"
MOUNT_DEV="$1"

#############
# FUNctions
# in case you got them in your roots ~/bin/my_functions
# coment out the source-lines and comment the function lines
#############################################################
#source ~/bin/my_functions/check_root
#source ~/bin/my_functions/ask_for

function check_root {
if [[ $(id -u) -ne 0 ]]
then
    echo "You need to rerun as root"
    exit 1
fi
}



function ask_for {
printf "\n\t You want to go on? \n\t Say yes or no: "

read answer
case $answer in 
[Yy]es | [Yy]  ) echo "ok: ";;
 *) printf "\n\t You didn't answer yes. \n\t The script will die \n" 
   umount "$MOUNT_POINT"
   exit 1 ;;
esac
}


#####################################################
# Check for root, check if device is given and if its a block device
#####################################################
check_root
[[  $# =  1  ]] || {  echo "no device added. Rerun" ;  exit 1 ; } 
[[ -b $1 ]] ||  { echo "not a valid block device. Rerun " ;  exit 2 ; }
[[ -d "$MOUNT_POINT" ]] || { echo "creating $MOUNT_POINT" && mkdir "$MOUNT_POINT" ; } 
echo 

############
# Mount it
############
{ mount  "$MOUNT_DEV" "$MOUNT_POINT" && echo "successfully mounted" ;  } || { echo "mount failed. Exit" ;  exit 3 ; }

##############################
# list it and ask for going on
##############################
echo "here is the actual content of the mounted device $MOUNT_DEV on $MOUNT_POINT"
ls "$MOUNT_POINT"
ask_for

echo "we will mount /dev /proc and /sys on it"

################################
# mounting /dev /proc and /sys
################################
{ mount -o bind /dev "$MOUNT_POINT"/dev && echo "/dev mounted" ;  } || { echo "mounting of dev failed" ; exit 4 ; }

{ mount -t proc /proc  "$MOUNT_POINT"/proc  && echo "/proc mounted" ; } || { echo "mounting of proc failed" ; exit  5 ;   }

{ mount -o bind /sys   "$MOUNT_POINT"/sys  && echo "/sys  mounted" ; } || { echo "mounting of sys failed" ; exit  6 ;  }

#################################
# chroot
################################
chroot "$MOUNT_POINT"

######################################
# After all is done, 
# We will exit chroot-env
# and need to umount the whole shebang
####################################### 

{ umount "$MOUNT_POINT"/{sys,proc,dev} && echo "sys proc and dev umounted again" ; } || { echo "umounting of sys,proc or dev failed. Check whats wrong. " ; exit 7 ; }

{ umount "$MOUNT_POINT" && echo "$MOUNT_POINT umounted again. Looks like all is fine. " ; } || {  "umounting of $MOUNT_POINT failed. Check whats wrong " ; exit 8 ; } 


printf "\n\n\t Looks like all went fine. \n\t Bye. \n\n "

exit 0
I mainly post this cause i am a bit proud that it did work. Sure i am happy to hear about errors and all that anyway (No problem with a "that sucks big times". I am a beginner and i know it).
Obviously i like it chatty. No need to point that out, cause i need/want it that way (for troubleshooting). If someone wants to i will rewrite it without all those: "lala succeed" and "lala failed" so it is more obvious whats going on. Then we can talk about that.
Thanks.
"I am not fine with it, so there is nothing for me to do but stand aside." M.D.

smallchange
Posts: 1740
Joined: 2009-05-04 15:56

Re: bash script to chroot

#2 Post by smallchange »

This looks useful. The only suggestion I have is that in some cases I want to fix a system that has /boot on a different partition and it would be nice to have that as an option. Maybe -b that is the device name?

User avatar
nadir
Posts: 5964
Joined: 2009-10-05 22:06
Location: away

Re: bash script to chroot

#3 Post by nadir »

This looks useful.
Thank you. :D
For me and here it is a really cool piece of code. Before it was a bunch of commands, with typos and all. Now it is one command (+ su and + exit to exit root, but that i needed to do anyway).
The only suggestion I have is that in some cases I want to fix a system that has /boot on a different partition and it would be nice to have that as an option.
Heck, i really am bound to my own little world. As i don't do it that way i didn't think about it and wouldn't know how to do it.
I guess for the ones who got the system set-up that way it wouldn't be a big problem to change it that way.
Maybe -b that is the device name?
I don't understand that. Sorry. The part in my code which contains -b is a bit beyond me too (dbbolton mentioned it once, i add it for .... i don't know exactly why, as i am not that sure what a block-device is. I added it cause he said so.)
"I am not fine with it, so there is nothing for me to do but stand aside." M.D.

smallchange
Posts: 1740
Joined: 2009-05-04 15:56

Re: bash script to chroot

#4 Post by smallchange »

About -b I was referring to a possible command line argument parsed by getopts. The user would then have the option of using a command like
nadir_chroot.sh -b /dev/sda3 /dev/sda5
and this would use /dev/sda5 as the chroot, mounted on /media/disk and /dev/sda3 would be mounted on /media/disk/boot.

My systems tend to mount USB drives as /media/disk. What would happen if I had a USB drive mounted there and I ran your script?

User avatar
nadir
Posts: 5964
Joined: 2009-10-05 22:06
Location: away

Re: bash script to chroot

#5 Post by nadir »

Thanks for the getopt idea. Bit of time is needed for that.
(bit more than a bit, that was irony )

Mhhh... just shooting in the dark:
As far i see if you mount /dev/whatever on a mount-point where already something is mounted (the stick in your case), that something (the stick) just gets invisible as long /dev/whatever is mounted there. So, if that is right, there should be no problems. But:
I didn't think about it. I think.
Perhaps adding a "umount /media/disk if /media/disk is already mounted" just at the beginning. I will try it later (tomorrow or the day after that). Yep, you are right, one should keep that things in mind. And there are tons of "that things".

Thats how it would look like if i mount a stick on /media/disk before running ./do_chroot /dev/sda7

Code: Select all

# mount
/dev/sda1 on / type ext4 (rw,noatime,errors=remount-ro)
tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)
/dev/sda5 on /home type ext3 (rw,noatime)
fusectl on /sys/fs/fuse/connections type fusectl (rw)
# mount /dev/sdf1 /media/disk
# ls /media/disk
debian-505-i386-netinst.iso  ldlinux.sys  menu.c32  syslinux.cfg  ubninit  ubnkern
# ./do_chroot /dev/sda7

Code: Select all

Tue Aug 17 17:16:45 CEST 2010


successfully mounted
here is the actual content of the mounted device /dev/sda7 on /media/disk
bin   cdrom  etc   initrd.img  lost+found  mnt	proc  sbin     srv	 sys  usr  vmlinuz
boot  dev    home  lib	       media	   opt	root  selinux  swapfile  tmp  var

	 You want to go on? 
	 Say yes or no: yes
ok: 
we will mount /dev /proc and /sys on it
/dev mounted
/proc mounted
/sys  mounted
root@debian-sid:# exit
exit
sys proc and dev umounted again
/media/disk umounted again. Looks like all is fine. 


	 Looks like all went fine. 
	 Bye. 

 # ls /media/disk
debian-505-i386-netinst.iso  ldlinux.sys  menu.c32  syslinux.cfg  ubninit  ubnkern
So: it should work anyway, but doesn't look like a "proper" solution.

PS: Mhhh... as far i see you (you who knows that /media/disk is already in use in your filesystem) would simply need to change it to a mount-point you usually don't use here (-> at the very beginning):

Code: Select all

############
# Variables
############

MOUNT_POINT="/media/my_chroot"
MOUNT_DEV="$1"
"I am not fine with it, so there is nothing for me to do but stand aside." M.D.

User avatar
TobiSGD
Posts: 859
Joined: 2010-05-08 22:27
Location: Hannover, Germany

Re: bash script to chroot

#6 Post by TobiSGD »

It should work to use /etc/mtab to determine if the mountpoint is already in use.

Code: Select all

grep "$MOUNTPOINT" /etc/mtab > /dev/null
will deliver exitcode 0 if the mountpoint is already in use, otherwise it would exit with 1.

User avatar
nadir
Posts: 5964
Joined: 2009-10-05 22:06
Location: away

Re: bash script to chroot

#7 Post by nadir »

TobiSGD wrote:It should work to use /etc/mtab to determine if the mountpoint is already in use.

Code: Select all

grep "$MOUNTPOINT" /etc/mtab > /dev/null
will deliver exitcode 0 if the mountpoint is already in use, otherwise it would exit with 1.
Thanks. Good idea. I will try that, but it will take a few days.
"I am not fine with it, so there is nothing for me to do but stand aside." M.D.

Post Reply