2

Recently, I found that lsblk doesn't show it's output sorted.

$lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdb      8:16   0 149.1G  0 disk 
├─sdb2   8:18   0  99.1G  0 part /windows/windows-10
└─sdb1   8:17   0    50G  0 part /windows/windows-xp
sr0     11:0    1  1024M  0 rom  
sdc      8:32   0 931.5G  0 disk 
└─sdc1   8:33   0 931.5G  0 part /mnt/data
sda      8:0    0 111.8G  0 disk 
├─sda2   8:2    0     1K  0 part 
├─sda5   8:5    0     4G  0 part [SWAP]
├─sda1   8:1    0    20G  0 part /
└─sda6   8:6    0  87.8G  0 part /home

Same thing happens to both of my arch computer.

I'm not sure why does it do this. Is there anyone has the same problem? Can someone gives me some clue what's going on?

I'm using Arch linux 64 bit with kernel 4.8.3-1-ARCH.

2 Answers 2

3
pi@odroid64:~$ lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda           8:0    0 111.8G  0 disk
├─sda1        8:1    0 104.9G  0 part /mnt/usbstorage
└─sda2        8:2    0   6.9G  0 part
mmcblk0     179:0    0   7.4G  0 disk
├─mmcblk0p1 179:1    0   128M  0 part /media/boot
└─mmcblk0p2 179:2    0   7.3G  0 part /
pi@odroid64:~$ lsblk -x NAME
NAME      MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
mmcblk0   179:0    0   7.4G  0 disk
mmcblk0p1 179:1    0   128M  0 part /media/boot
mmcblk0p2 179:2    0   7.3G  0 part /
sda         8:0    0 111.8G  0 disk
sda1        8:1    0 104.9G  0 part /mnt/usbstorage
sda2        8:2    0   6.9G  0 part
pi@odroid64:~$

lsblk -x NAME

-x gives you the option to sort the output, the argument to -x can be any of

Available columns (for --output):
        NAME  device name
       KNAME  internal kernel device name
     MAJ:MIN  major:minor device number
      FSTYPE  filesystem type
  MOUNTPOINT  where the device is mounted
       LABEL  filesystem LABEL
        UUID  filesystem UUID
    PARTTYPE  partition type UUID
   PARTLABEL  partition LABEL
    PARTUUID  partition UUID
   PARTFLAGS  partition flags
          RA  read-ahead of the device
          RO  read-only device
          RM  removable device
     HOTPLUG  removable or hotplug device (usb, pcmcia, ...)
       MODEL  device identifier
      SERIAL  disk serial number
        SIZE  size of the device
       STATE  state of the device
       OWNER  user name
       GROUP  group name
        MODE  device node permissions
   ALIGNMENT  alignment offset
      MIN-IO  minimum I/O size
      OPT-IO  optimal I/O size
     PHY-SEC  physical sector size
     LOG-SEC  logical sector size
        ROTA  rotational device
       SCHED  I/O scheduler name
     RQ-SIZE  request queue size
        TYPE  device type
    DISC-ALN  discard alignment offset
   DISC-GRAN  discard granularity
    DISC-MAX  discard max bytes
   DISC-ZERO  discard zeroes data
       WSAME  write same max bytes
         WWN  unique storage identifier
        RAND  adds randomness
      PKNAME  internal parent kernel device name
        HCTL  Host:Channel:Target:Lun for SCSI
        TRAN  device transport type
  SUBSYSTEMS  de-duplicated chain of subsystems
         REV  device revision
      VENDOR  device vendor

more information can be found ITFM

2
  • 1
    But then it doesn't show the tree.
    – Rio6
    Commented Nov 2, 2016 at 1:31
  • @Rio6 - it does if you add the -T switch, available with newer versions. John Allard could add this info to the answer. HTH. Commented Feb 13, 2022 at 0:57
0

I wrote an answer in Ask Ubuntu to deal with this issue.

Unsorted output

$ lsblk | egrep -v ^loop
NAME         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
nvme0n1      259:0    0   477G  0 disk 
├─nvme0n1p9  259:9    0   7.9G  0 part [SWAP]
├─nvme0n1p7  259:7    0  23.1G  0 part /mnt/old
├─nvme0n1p5  259:5    0   859M  0 part 
├─nvme0n1p3  259:3    0    16M  0 part 
├─nvme0n1p1  259:1    0   450M  0 part 
├─nvme0n1p8  259:8    0     9G  0 part /mnt/e
├─nvme0n1p10 259:10   0  27.2G  0 part /mnt/clone
├─nvme0n1p6  259:6    0  45.1G  0 part /
├─nvme0n1p4  259:4    0 363.2G  0 part /mnt/c
└─nvme0n1p2  259:2    0    99M  0 part /boot/efi
mmcblk0      179:0    0 119.1G  0 disk 
└─mmcblk0p1  179:1    0 119.1G  0 part /media/rick/SANDISK128
sr0           11:0    1  1024M  0 rom  
sda            8:0    0 931.5G  0 disk 
├─sda4         8:4    0   450M  0 part 
├─sda2         8:2    0   128M  0 part 
├─sda5         8:5    0  11.4G  0 part 
├─sda3         8:3    0   919G  0 part /mnt/d
└─sda1         8:1    0   500M  0 part 

Sorted output

$ lsblk | egrep -v ^loop | sblk
NAME         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
nvme0n1      259:0    0   477G  0 disk 
├─nvme0n1p1  259:1    0   450M  0 part 
├─nvme0n1p2  259:2    0    99M  0 part /boot/efi
├─nvme0n1p3  259:3    0    16M  0 part 
├─nvme0n1p4  259:4    0 363.2G  0 part /mnt/c
├─nvme0n1p5  259:5    0   859M  0 part 
├─nvme0n1p6  259:6    0  45.1G  0 part /
├─nvme0n1p7  259:7    0  23.1G  0 part /mnt/old
├─nvme0n1p8  259:8    0     9G  0 part /mnt/e
├─nvme0n1p9  259:9    0   7.9G  0 part [SWAP]
└─nvme0n1p10 259:10   0  27.2G  0 part /mnt/clone
mmcblk0      179:0    0 119.1G  0 disk 
└─mmcblk0p1  179:1    0 119.1G  0 part /media/rick/SANDISK128
sr0           11:0    1  1024M  0 rom  
sda            8:0    0 931.5G  0 disk 
├─sda1         8:1    0   500M  0 part 
├─sda2         8:2    0   128M  0 part 
├─sda3         8:3    0   919G  0 part /mnt/d
├─sda4         8:4    0   450M  0 part 
└─sda5         8:5    0  11.4G  0 part 

Bash script

Here is the bash script to sort lsblk output.

#!/bin/bash
# Ask Ubuntu: https://askubuntu.com/questions/1392560/how-to-change-lsblk-sort-order
oIFS="$IFS"                         # Save IFS
IFS='|'                             # Use "|" as array delimiter
declare -a partiions=()             # Partitions array for a given drive

add_part () {
    line="$1"                       # Confusing parameter $1 becomes obvious
    part=${line%% *}                # get partition name, then get number
    key=$(echo "$part" | grep -Eo '[0-9]+$')

    # If length of number is less than 2, prepend "0"
    if [[ "${#key}" < 2 ]]; then
        key="0$key"                 # Prepend "0" to single digit
    fi

    line="${line:2}"                # Strip out tree character
    partitions+=( "$key$line" )     # Old line "├─..." now array entry "99..."
}

sort_parts () {
    # Sort partitions array with sort key into new "sorted" array
    read -r -d '' -a sorted < <( 
        echo "${partitions[*]}" | tr "|" "\n" | sort | tr "\n" "|" )
    last_i=$(( ${#sorted[@]} - 1 )) # Last 0-based index in sorted array

    for ((i=0; i <= $last_i; i++)); do
        line="${sorted[i]}"         # Get array line at 0-based index
        line="${line:2}"            # Strip out sort key "99"
        if [[ $i -lt $last_i ]]; then
            echo "├─$line"          # Print a line that is not the last line
        else
            echo "└─$line"          # Print last line
        fi
    done
    partitions=()                   # Empty partitions array for the next drive
}

# Main Loop
while read line
do
    first="${line:0:2}"
    if [[ "$first" == "├─" || "$first" == "└─" ]]; then
        add_part "$line"            # Add special line to partitions array

        if [[ "$first" == "└─" ]]; then
            sort_parts              # Last partition. Sort and print array
        fi
    else
        echo "$line"                # Simply print a regular line
    fi

done < "${1:-/dev/stdin}"           # Read from file $1 or from standard input


IFS="$oIFS"                         # Restore old IFS

Remember to put the script into your path and make it executable with:

chmod a+x /path/to/script

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .