コマンドの引数として--my_argument`catsome_file`を使用する

0
2022.03.06

いくつかのファイルに基づいた出力でコマンドを実行しています。そのため、コマンド内のファイルをcatします。ただし、ファイルに何も含まれていない場合、これは問題があります

mkbootimg --kernel "$SCRIPT_DIR/devices/$DEVICE/kernel/k/arch/arm64/boot/Image" \
--ramdisk boot.img-ramdisk \
--dtb boot.img-dtb \
--cmdline "$(cat boot.img-cmdline)" \
--base `cat boot.img-base` \
--kernel_offset `cat boot.img-kernel_offset` \
--ramdisk_offset `cat boot.img-ramdisk_offset` \
--tags_offset `cat boot.img-tags_offset` \
--dtb_offset `cat boot.img-dtb_offset` \
--os_version `cat boot.img-os_version` \
--os_patch_level `cat boot.img-os_patch_level` \
--pagesize `cat boot.img-pagesize` \
--header_version `cat boot.img-header_version` \
--hashtype `cat boot.img-hashtype` \
--board `cat boot.img-board` \
--ramdisk_offset `cat boot.img-ramdisk_offset` \
-o ../boot.img)

たとえば、 boot.img-boardに何もない場合は、

 --board --ramdisk_offset 0x10000

したがって、 board--ramdisk_offsetであると見なし、 mkbootimg0x10000の別の引数として解釈します。

この問題を解決するための最良の方法は何ですか?実際にboot.img-board内に何かがある場合にのみ、 --boardを実行できますか?

回答
2
2022.03.07

ハンヌの答えに基づいて、しかしもし…?を指定したので、

 args=(
        --ramdisk boot.img-ramdisk
        --dtb boot.img-dtb
        --cmdline "$(cat boot.img-cmdline)"
)
for param in base kernel_offset ramdisk_offset tags_offset dtb_offset os_version \
            os_patch_level pagesize header_version hashtype board ramdisk_offset
do
        f="boot.img-$param"
        if [ "$(wc -w < "$f")" = 1 ]
        then
                args+=("--$param" "$(cat "$f")")
        else
                printf 'Problem with %s.\n' "$f"
        fi
done
args+=(-o ../boot.img)
mkbootimg "${args[@]}"

一貫してファイルに名前を付けていただきありがとうございます。それは仕事を容易にしました。

これにより、 argsという配列が作成され、固定パラメーター( ramdiskdtb 、およびcmdline )で開始されます。 ( boot.img-cmdlineファイルの内容を確認する場合は、それに応じてスクリプトを拡張するか、必要に応じてヘルプを求めてください。)次に、コードはファイル駆動型パラメーターをループします。ファイルに単語が1つだけ含まれている場合は、オプションと値が配列に追加されます。それ以外の場合、パラメーターはスキップされます。ループの後に、 -oオプションを追加し、コマンドを実行します。

ノート:

  • 私はあなたのコードをかなり忠実にコピーし、 ramdisk_offsetを2回含めるようにしましたが、それはタイプミスだと思います。

  • このサイトの他の場所で説明されている理由により、 `…`を同等の$(…)に変更しました。

  • 正確に1つの単語を含むファイルのみを処理するコードを作成しました。複数の単語を含むファイルがある可能性があることに気付いた場合は、コードを変更する必要があります。

  • 必要に応じて、この複数行の構成に円記号を含めることができます。

     args=( \
            --ramdisk boot.img-ramdisk \
            --dtb boot.img-dtb \
            --cmdline "$(cat boot.img-cmdline)" \
    )
    

    しかし、あなたはそうする必要はありません。シェルが(を検出すると、一致する)が検出されるまで読み取りを継続する必要があることがわかります。

  • また、必要に応じて、これをすべて1行で実行できます。

     args=(--ramdisk boot.img-ramdisk --dtb boot.img-dtb --cmdline "$(cat boot.img-cmdline)")
    
  • 読みやすさと編集性のために、パラメータを別々の行にリストすることをお勧めします。

     for param in \
            base \
            kernel_offset \
            ramdisk_offset \
            tags_offset \
            dtb_offset \
            os_version \
            os_patch_level \
            pagesize \
            header_version \
            hashtype \
            board \
            ramdisk_offset
    do
            …
    
  • これはbashで実行する必要があります。

    • スクリプトを不格好な方法で実行している場合は、 bash script.shと言う必要があります。 sh script.shと言えば、デフォルトのシェル( /bin/sh )を実行しています。これはPOSIXに準拠している可能性がありますが、おそらくbashではなく、配列をサポートしていない可能性があります。
    • 実行可能スクリプト( chmod +x )として実行している場合は、スクリプトを「シバン」で開始する必要があります。
       #!/bin/bash
      
      また
      #!/usr/bin/env bash
      
      これは、スクリプトの最初の行である必要があります。

    PS実際、bashを使用できない場合は、別の方法があります。ここを参照してください。

1
2022.03.07

あなたはにタグを付けたので、Bash固有の構文を使用することを躊躇しません。

信頼できる方法は、コマンド(または少なくとも引数)を配列として作成することです。条件付きで配列に追加できます。例:

 #!/bin/bash

unset arr
arr=(--ramdisk boot.img-ramdisk)
arr+=(--dtb boot.img-dtb)
arr+=(--option 'value    with     spaces')
# etc.

# essence begins
value=$(<boot.img-board)
if [ "$value" ]; then
   arr+=(--board "$value")
fi
# essence ends

arr+=('final argument')
printf '<%s>\n' "${arr[@]}"

適切なアレイを構築した後、 mkbootimg "${arr[@]}"の代わりにprintf …を使用します。