Detect if booted drive is internal or usb drive

Hello.

I have some bootable usb stick.
Within a script, how to detect if the system booted from internal drive or from usb.

The number of sda, sdb, … sdx internal device are unknown.

Any help is welcome.

Hi
Are you after the actual boot method/partition or what it booted, as in the root device?

You can see the root device via;


cat /proc/cmdline

Depends on the setup as these days it references UUID, the following needs to be run as root user which will give references;


blkid
lsblk -o NAME,UUID

The boot method could be legacy/mbr or uefi, is this what you are after?

The question you’re asking has been asked since USB connected drives first appeared because systems have been built using USB in place of other (like SATA) connections.

AFAIK, at the hardware level it’s nearly impossible to detect any difference.
But, it’s possible to pass some hints to the system like mounting through fstab, in that case the system probably still can’t know for sure the drive is internal or external but will know that the drive is to be mounted automatically during boot.

Complicating a bit further, there may also be more than one way to mount a drive after detection.

I guess the big question from a scripting perspective is why you would need to know whether the drive is mounted internally or externally?
It’s more common to do things like detect whether the drive is found.

Or, by “internal drive” are you assuming that the drive is something other than USB?

AFAIK,
TSU

$ (cd /sys/block/sdb/device; pwd -P )
/sys/devices/pci0000:00/0000:00:14.0/**usb**2/2-2/2-2:1.0/host2/target2:0:0/2:0:0:0
erlangen:~ # readlink -f  /sys/block/sd*
/sys/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/block/sda
/sys/devices/pci0000:00/0000:00:1f.2/ata2/host1/target1:0:0/1:0:0:0/block/sdb
/sys/devices/pci0000:00/0000:00:1f.2/ata4/host3/target3:0:0/3:0:0:0/block/sdc
/sys/devices/pci0000:00/0000:00:14.0/usb2/2-10/2-10:1.0/host6/target6:0:0/6:0:0:0/block/sdd
erlangen:~ # 

Yes.
Great .
:good:

Of course I know how much internal drive there are on the current computer.
And I know that there is a swap partition named ‘LNX_SWAP_USB’ on each opensuse bootable usb disk.

ASUS-G750JZ:~ # cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-4.12.14-lp151.28.20-default root=UUID=144da1f6-e4e7-402a-b33c-537dd00171c6 resume=/dev/disk/by-label/LNX_SWAP_USB ipv6.disable=1 plymouth.enable=0 mitigations=auto
ASUS-G750JZ:~ # blkid | grep '144da1f6-e4e7-402a-b33c-537dd00171c6'
/dev/sdc4: LABEL="LNX_SLASH_USB" UUID="144da1f6-e4e7-402a-b33c-537dd00171c6" TYPE="ext4" PARTLABEL="slash" PARTUUID="461a7323-a511-41e3-b586-c1aa794e9695"
ASUS-G750JZ:~ # (cd /sys/block/sdb/device; pwd -P )
/sys/devices/pci0000:00/0000:00:1f.2/ata5/host4/target4:0:0/4:0:0:0
ASUS-G750JZ:~ # readlink -f  /sys/block/sd*
/sys/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/block/sda
/sys/devices/pci0000:00/0000:00:1f.2/ata5/host4/target4:0:0/4:0:0:0/block/sdb
/sys/devices/pci0000:00/0000:00:14.0/usb2/2-5/2-5:1.0/host6/target6:0:0/6:0:0:0/block/sdc
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/host7/target7:0:0/7:0:0:0/block/sdd
ASUS-G750JZ:~ #

This system is booted from internal disk ( sda or sdb ) or booted from external usb disk ( sdc or sdd ) ?

Seems not helping.

Thank you every body for helping.

Try again:

erlangen:~ # readlink -f  /sys/block/sd*
/sys/devices/pci0000:00/0000:00:1f.2/**ata1**/host0/target0:0:0/0:0:0:0/block/**sda**
/sys/devices/pci0000:00/0000:00:1f.2/ata2/host1/target1:0:0/1:0:0:0/block/sdb
/sys/devices/pci0000:00/0000:00:1f.2/ata4/host3/target3:0:0/3:0:0:0/block/sdc
/sys/devices/pci0000:00/0000:00:14.0/usb4/4-6/4-6:1.0/host7/target7:0:0/7:0:0:0/block/sde
erlangen:~ # df /
Filesystem     1K-blocks     Used Available Use% Mounted on
/dev/**sda2 **      30832548 18414784  10828516  63%** /**
erlangen:~ #

Hi
The logic seems flawed…?

There are multiple device types as well…


readlink -f  /sys/block/[mm,nv,sd]*

/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/nvme/nvme0/nvme0n1
/sys/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/block/sda
/sys/devices/pci0000:00/0000:00:1f.2/ata2/host1/target1:0:0/1:0:0:0/block/sdb
/sys/devices/pci0000:00/0000:00:1a.0/usb3/3-1/3-1.5/3-1.5:1.0/host6/target6:0:0/6:0:0:0/block/sdc

 df -k /
Filesystem     1K-blocks     Used Available Use% Mounted on
/dev/nvme0n1p1  41943040 14280144  27085616  35% /

Question, what block device did I boot from?

As Tsu2 already hinted to, it is unclear what the definition of some of the terms used here are.

E.g. What is the definition of “booted drive” (as mentioned in the title):

  • the device from which the used Grub is loaded?
  • or the device from which the kernel is loaded?
  • or the device that during boot is mounted on / ? (this seems the one that many assume here as being what is asked for, but I am not sure)

All can be on different file systems and thus on different partitions and those can again be on the same or different mass-storage devices. Go figure.

I also wonder about the choice “from internal drive or from usb”. I can understand USB vs. PCI and/or SCSI and maybe other types of bus/connection. I also can understand the contrast between internal and external (but I have no idea how a Linux system ever can decide if a mass-storage device is inside or outside the main box of a computer). As it is put here I assume it can only lead to confusuion.

Sure.:wink:

linux-udd7:~ # readlink -f $(find /sys/block -maxdepth 1 -type l)
/sys/devices/pci0000:00/0000:00:14.0/usb4/4-6/4-6:1.0/host6/target6:0:0/6:0:0:0/block/sdd
/sys/devices/pci0000:00/0000:00:1f.2/ata2/host1/target1:0:0/1:0:0:0/block/sdb
/sys/devices/pci0000:00/0000:00:1f.2/ata3/host2/target2:0:0/2:0:0:0/block/sr0
/sys/devices/pci0000:00/0000:00:1f.2/ata4/host3/target3:0:0/3:0:0:0/block/sdc
/sys/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/block/sda
linux-udd7:~ # 

Assertions completely outside my question.

You don’t read the question.
I said :

I have some bootable usb stick.
Within a script, how to detect if the system booted from internal drive or from usb.

A computer can boot from any bootable device.
An internal drive is a drive which is inside the enclosure; and then an external drive is outside the enclosure.
A computer can boot from an usb stick which is outside the enclosure or boot from an internal disk which is inside the enclosure.
A script can be run from any folder.
The same script can run from a folder on an internal disk or on an external disk.
The same script can run on any operating system.

Now, the computer started, and the script is running.
The script is very stupid because it don’t know from where it is running, and I must help it.

And the malcolmlewis’s answer in 43 characters ( including
) is brillant.

Depends on the BIOS, basicaly correct.

Same as I said in my post. But it is not something the operating system can detect. It “sees” just a device on a bus and never if that bus sneaks out of the enclosure.

The computer can not detect if this is a stick, or any other form (card, revolving disk, SSD).
The computer can also boot from an USB device that is inside the enclosure.
The computer can also boot from a PCI device outside the enclosure.
There is no strickt connection between ‘internal vs. external’ and ‘USB vs other bus’.

With some restrictions (mainly permissions in the path through the directories up to and including those of the script file), correct.

As the system sees no difference that is true by implication of things mentioned above.

That is of course incorrect. Try to run a bash script on an IBM 360 operating system.

Don’t blame the script. The operating system is there to hide such hardware trivialities from the system’s users. And the running script is only a user of the system.

BTW, I have seen this more often. Malcolm is a star in assuming the correct information that misses from a problem description. But that gift is not everybody’s.

Hi
So in your script use the pwd (present working directory) command to tell it where it is running from as a reference? Or send it to a specific directory first to run eg /tmp

I wrote a script to configure all computers the same way whether they are new just out of their box or whether they have been reformatted for any reason.
This script is located on a non bootable independent flash drive.

This script can also be used to configure a flash drive on which a linux OS has been installed.

When the script is executed, some operations are not executed if the system has booted from a memory stick.

    UUID=$(cat /proc/cmdline | sed 's/.*root=UUID=\(.*\)resume/\1/' | cut -d ' ' -f1)
    DEVICE_NAME=$(lsblk -l -o NAME,UUID | grep $UUID | cut -d ' ' -f1 )
    SDX_DEVICE="${DEVICE_NAME::-1}"
    BOOT=$(lsblk -do name,tran | grep $SDX_DEVICE | cut -d ' ' -f3 )

Example :


XXXX-YYYYYY-USB:~ # 
XXXX-YYYYYY-USB:~ #     UUID=$(cat /proc/cmdline | sed 's/.*root=UUID=\(.*\)resume/\1/' | cut -d ' ' -f1)
XXXX-YYYYYY-USB:~ #     DEVICE_NAME=$(lsblk -l -o NAME,UUID | grep $UUID | cut -d ' ' -f1 )
XXXX-YYYYYY-USB:~ #     SDX_DEVICE="${DEVICE_NAME::-1}"
XXXX-YYYYYY-USB:~ #     BOOT=$(lsblk -do name,tran | grep $SDX_DEVICE | cut -d ' ' -f3 )
XXXX-YYYYYY-USB:~ #     echo "The system has booted from : $BOOT"
The system has booted from : usb
XXXX-YYYYYY-USB:~ # 

Thank you for your comments.