bash + arg를 Linux 머신의 디스크 중 하나와 비교하는 방법

bash + arg를 Linux 머신의 디스크 중 하나와 비교하는 방법

다음 명령을 사용하여 Linux 시스템의 디스크 장치를 캡처할 수 있습니다.

lsblk -lnb | numfmt --to=iec --field=4 | grep disk | awk '{print $1}'
sda
sdb
sdc
sdd

내 Bash 스크립트에서는 다음 줄을 사용하여 스크립트의 매개 변수가 내 컴퓨터의 디스크 중 하나와 일치하는지 테스트합니다.

if [[ ` lsblk -lnb | numfmt --to=iec --field=4 | grep disk | awk '{print $1}' | grep -c $arg ` != 0 ]] 
then
echo “argument is a disk”
.
.
.

fi

다음과 같이 스크립트를 실행합니다.

bash /tmp/verify_disks  <some arg>

그러나 케이스 $arg가 잘못되었거나 arg=”—help”케이스 $arg가 null인 경우 다음 예외가 발생합니다.

Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.

$arg그렇다면 내 Linux 시스템에 이러한 디스크 중 하나가 포함되어 있는지 확인하는 올바른 방법은 무엇입니까?

답변1

명령의 대부분 구성 요소를 사용하지 않는 것 같습니다. 필요한 것은 다음과 같습니다.

lsblk -lnb | awk '$NF=="disk"{print $1}'

grep그런 다음 인수가 제공되지 않을 때 오류 메시지를 방지하려면 주어진 인수를 인용해야 합니다.무엇내용이 빈 문자열인 경우에도 검색합니다.

if [[ "$(lsblk -lnb | awk '$NF=="disk"{print $1}' | grep -c "$arg")" != 0 ]]; then
    echo "argument is a disk"
fi

그러나 아무것도 지정하지 않으면 모든 것(빈 줄 포함)이 빈 문자열과 일치하므로 "argument is disk"가 반환됩니다.

$ echo foo | grep -c ""
1
$ echo "" | grep -c ""
1

이 문제를 피하는 쉬운 방법이자 아주 좋은 습관은 다음과 같습니다.언제나주장의 타당성을 확인하십시오 – ​​먼저 주장을 확인하십시오.

#!/bin/bash

if [[ -z "$1" ]]; then
  echo "The script needs at least one non-empty argument"
  exit 1
fi


arg="$1"

if [[ "$(lsblk -lnb | awk '$NF=="disk"{print $1}' | grep -c "$arg")" != 0 ]]; then
  echo "argument is a disk"
else
  echo "not a disk!"
fi

답변2

lsblkJSON 출력이 허용되므로 이를 jq사용하여 주어진 인수가 디스크인지 여부를 결정하는 것이 자연스러운 것 같습니다.

#!/bin/sh

if lsblk -J | jq -e --arg name "$1" '.blockdevices[] | select(.type == "disk" and .name == $name)' >/dev/null
then
    printf '"%s" is a disk\n' "$1"
else
    printf '"%s" is not a disk\n' "$1"
fi

이는 스크립트의 첫 번째 매개변수가 비어 있거나 누락되었거나 의미가 없는 경우를 올바르게 처리합니다.

-e옵션을 사용하면 jq마지막으로 평가된 값에 따라 종료 상태로 유틸리티가 종료됩니다. 예를 들어, 마지막으로 평가된 표현식( select())이 이면 0이 아닙니다.null

답변3

한 가지 가능성은 두 개의 if 수표를 갖는 것입니다. 먼저 $1(첫 번째 인수)를 사용할 수 있는지 확인한 다음(0이 아니고 --help가 아님) 이를 lsblk-Output과 비교합니다. 예를 들어:

#!/bin/env bash
if [[ -z "${1}" ]] || [[ "--help" == ${1} ]]; then
    echo "useful usage goes here"
else
    if [[ ` lsblk -lnb | numfmt --to=iec --field=4 | grep disk | awk '{print $1}' | grep -c ${1} ` != 0 ]]; then
        echo "argument is a disk"
    fi
fi

또 다른 팁: lsblk의 출력에 관심이 없다면 왜 포맷해야 할까요? lsblk가 디스크 라인만 제공할 수 있는데 왜 "디스크" 라인을 grep하겠습니까? 따라서 if 문은 다음과 같이 단축될 수 있습니다(적어도 lsblk 버전이 알고 있는 경우 -d).

if lsblk -dn | awk '{ print $1 }' | grep -wq $1; then

또는 더 짧을 수도 있습니다(팁 감사합니다, muru(맨 페이지에 더 주의를 기울였어야 했는데...)):

if lsblk -dn -o name | grep -wq $1; then

관련 정보