lsblk 出力がソートされていない

lsblk 出力がソートされていない

最近、lsblk出力がソートされていないことに気付きました。

$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

私の両方のArchコンピューターで同じことが起こります。

なぜそうなるのかわかりません。同じ問題を抱えている人はいますか? 何が起こっているのか、何かヒントをくれる人はいますか?

私はカーネル 4.8.3-1-ARCH を搭載した Arch Linux 64 ビットを使用しています。

答え1

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出力をソートするオプションがあり、引数は-x以下のいずれかになります。

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

詳細はITFMをご覧ください

答え2

私は書いた答えUbuntuに質問するこの問題に対処するため。

ソートされていない出力

$ 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 

ソートされた出力

$ 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スクリプト

出力をソートする bash スクリプトを次に示しますlsblk

#!/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

スクリプトをパスに配置し、次のように実行可能にすることを忘れないでください。

chmod a+x /path/to/script

関連情報