프로그래밍 방식으로 루트 파티션의 장치 이름/기본 이름을 어떻게 확인할 수 있습니까?

프로그래밍 방식으로 루트 파티션의 장치 이름/기본 이름을 어떻게 확인할 수 있습니까?

참고: 다음 질문 드라이브 이름? "/dev/sda"의 "sda" 부분에 대한 올바른 용어는 무엇입니까?

반면:

  1. 나는 시스템을 가지고 있습니다(이 경우에는 Raspberry Pi이지만 이는 모든 'nix 시스템과 관련될 수 있습니다).
  2. Linux 버전을 실행 중이며 모든 일반 Linux 명령이 작동한다고 가정합니다.
  3. 부팅 장치는 SD 카드 또는 USB 연결 저장 장치일 수 있습니다.
  4. 연결된 저장 장치에서 부팅하는 경우 장치 "basename"은 sd(x)입니다.
  5. SD 카드에서 부팅하는 경우 장치 "basename"은 "mm(xxxx)"와 같은 것으로 변경됩니다.

내가 하고 싶은 일: 프로그래밍 방식으로(가능한 경우 쉘 스크립트에서) 장치 유형에서 이를 실행하고 실행된 장치에 따라 특정 특성을 변경할 수 있기를 원합니다.

간단한 예:

Boot device = "mmxxxxx"
   Print "Booted from SD card!"
Boot device = "sda"
   Print "Booted from Attached Storage!"

내가 원하는 것은 루트 파티션이 시작된 기본 장치 유형(더 나은 용어로)을 추출하는 것입니다(루트 파티션으로 마운트된 장치에 따라 "sd", "mm" 또는 기타 이름. )

루트 디렉토리에 마운트된 장치를 어떻게든 나열할 수 있을 것 같습니다.모든 것이 나열되어 있지는 않습니다.mount를 선택한 다음 마지막 슬래시 뒤의 처음 두 글자를 추출합니다. . .

답변1

마운트 지점은 systemd에 의해 제어됩니다.

다음을 통해 시스템 마운트 단위 파일을 나열할 수 있습니다.

systemctl list-units --type=mount --all

예제 출력:

  -.mount                       loaded    active   mounted Root Mount                                   
  boot-efi.mount                loaded    active   mounted /boot/efi
...

루트 파티션은 에 의해 제어됩니다 -.mount.

systemctl status -- -.mount

● -.mount - Root Mount
     Loaded: loaded (/etc/fstab; generated)
     Active: active (mounted) since Wed 2024-02-07 
      Where: /
       What: /dev/sdaX
       Docs: man:fstab(5)
             man:systemd-fstab-generator(8)

장치 이름을 추출하려면:

systemctl status -- -.mount |grep -oP '(?<=What: ).*' |xargs basename

지적한대로 더 좋음@스틸드라이버이것에논평:

systemctl show --value --property=What -- -.mount |xargs basename

남성 systemd.mount:

What:마운트할 장치 노드, 파일 또는 기타 리소스에 대한 절대 경로를 가져옵니다.

답변2

Linux에 의존하지 않는 답변은 다음과 같습니다.체계( 명령 결과를 사용하고 구문 분석 /sys하려면 설치가 필요합니다.)lsblkjq

lsblk트리 출력에서 ​​종속성을 찾기 위한 모든 논리가 이미 포함되어 있다는 것을 알고 있으므로 이를 활용하여 작업을 수행할 수 있는 방법이 궁금합니다. 먼저 마운트 지점으로 필터링 --inverse하려면 Show Leaves First(아직 매개변수로 사용되지는 않음)를 사용하십시오 . /그런 다음 결과를 --json반복적으로 찾을 수 있습니다.

LVM, LUKS 등의 모든 레이어를 우회하여 최종 장치 이름을 출력합니다(디스크 파티션에서 LUKS보다 /over LV를 사용하는 시스템에서 테스트됨). RAID로 테스트되지 않았습니다(여러 장치를 출력하고 싶었습니다. 그렇지 않으면 이 jq스크립트가 실패합니다).

이것은 매우 긴 줄입니다:

lsblk --json --tree --inverse | jq -r '.blockdevices[] | if .mountpoints[] == "/" then ( .. | if .children? then empty else if .name then .name else empty end end ) else empty end'

또는 읽기가 더 쉽습니다.

lsblk --json --tree --inverse |
    jq -r '
.blockdevices[] |
    if .mountpoints[] == "/" then
        .. |
            if .children? then
                empty
            else
                .name // empty
            end
    else
        empty
    end
'

첫 번째 일치 항목을 수락 /하고 ..개체에 더 이상 하위 개체(일명 "children"고유한 형식의 하위 개체)가 포함되지 않을 때까지 개체에 대해 반복(사용)한 다음 해당 이름을 표시합니다.

결과의 처음 2개 문자만 얻으려면 추가로 | cut -c-2.

답변3

df /획득 에 사용되는 장비입니다 /. 열( --output=source) 및 행( )을 기준으로 tail -1필터링 할 수도 있습니다 .

% df --output=source / | tail -1
/dev/mapper/sys-root

답변4

이것은 간단한 방법입니다. 나는 이것을 내 컴퓨터에서만 테스트했습니다. 설치 명령의 출력이 다를 수 있습니다.

boot_device=( $(mount | grep boot) )
if [[ $(echo "${boot_device[0]}" | grep -c sd) -eq 1 ]]
then
echo "Booted from attached storage"
else 
echo "Booted from SD card!"
fi

else 대신 elif 구조를 사용할 수 있습니다. 예를 들면 다음과 같습니다.

elif [[ $(echo "${boot_device[0]}" | grep -c mm) -eq 1 ]]
then
echo "Booted from SD card!"
else
echo "ERROR: Something has gone horribly wrong!"
fi

답변을 수락하셨지만, mount 명령을 사용하여 이 작업을 수행하는 방법을 알아내는 데 몇 분이 걸렸기 때문에 답변으로 게시합니다.

관련 정보