bash + argをLinuxマシンのディスクの1つと比較する方法

bash + argをLinuxマシンのディスクの1つと比較する方法

次のコマンドを使用して、Linuxシステムのディスクデバイスをキャプチャできます。

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

私のBashスクリプトでは、次の行を使用して、スクリプトのパラメータが自分のコンピュータのディスクの1つと一致するかどうかをテストします。

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つが含まれていることを確認する正しい方法は何ですか?

答え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())がある場合はゼロではありません。null

答え3

1つの可能性は、2つの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

関連情報