شرح - تحقق من وجود وسيطة الإدخال في برنامج نصي Bash shell





script scripting (8)


غالبًا ما أستخدم هذا المقتطف للنصوص البسيطة:

#!/bin/bash

if [ -z "$1" ]; then
    echo -e "\nPlease call '$0 <argument>' to run this command!\n"
    exit 1
fi

أحتاج إلى التحقق من وجود وسيطة إدخال. لدي البرنامج النصي التالي:

if [ "$1" -gt "-1" ]
  then echo hi
fi

انا حصلت

[: : integer expression expected

كيف يمكنني التحقق من الوسيطة input أولاً لمعرفة ما إذا كانت موجودة؟




كتذكير صغير ، تعمل عوامل الاختبار الرقمية في Bash فقط على الأعداد الصحيحة ( -lt ، -ge ، -ge ، إلخ.)

أحب التأكد من أن النوتات $ mys الخاصة بنا

var=$(( var + 0 ))

قبل اختبارهم ، فقط للدفاع ضد الخطأ "[: integer arg المطلوبة".




محاولة:

 #!/bin/bash
 if [ "$#" -eq  "0" ]
   then
     echo "No arguments supplied"
 else
     echo "Hello world"
 fi



إذا كنت مهتمًا فقط باكتشاف ما إذا كانت هناك وسيطة معينة مفقودة ، فسيكون استبدال المعلمة أمرًا رائعًا:

#!/bin/bash
# usage-message.sh

: ${1?"Usage: $0 ARGUMENT"}
#  Script exits here if command-line parameter absent,
#+ with following error message.
#    usage-message.sh: 1: Usage: usage-message.sh ARGUMENT

في بعض الحالات ، تحتاج إلى التحقق مما إذا كان المستخدم قد مرر وسيطة إلى البرنامج النصي ، وإذا لم يكن كذلك ، فارجع إلى قيمة افتراضية. كما هو الحال في البرنامج النصي أدناه:

scale=${2:-1}
emulator @$1 -scale $scale

إذا لم يكن المستخدم قد -scale 1 ثانٍ ، فأنا أقوم بتشغيل محاكي الأندرويد مع -scale 1 بشكل افتراضي. ${varname:-word} هي مشغل توسع. هناك عوامل أخرى للتوسع أيضًا:

  • ${varname:=word} الذي يضبط الاسم غير المعرّف بدلاً من إرجاع قيمة word ؛
  • ${varname:?message} الذي يقوم إما بإرجاع varname إذا تم تعريفه وهو غير فارغ أو يقوم بطباعة message وإحباط البرنامج النصي (مثل المثال الأول)؛
  • ${varname:+word} والتي ترجع word فقط إذا تم تعريف varname وليست خالية؛ يعود لا شيء خلاف ذلك.



طريقة أخرى للكشف عن ما إذا تم تمرير الحجج إلى البرنامج النصي:

((!$#)) && echo No arguments supplied!

لاحظ أن (( expr )) يؤدي إلى تقييم التعبير وفقًا لقواعد حساب Shell .

من أجل الخروج في غياب أي حجج ، يمكن للمرء أن يقول:

((!$#)) && echo No arguments supplied! && exit 1

طريقة أخرى (مماثلة) لتوضيح ما ورد أعلاه:

let $# || echo No arguments supplied

let $# || { echo No arguments supplied; exit 1; }  # Exit if no arguments!

help let يقول:

let: let arg [arg ...]

  Evaluate arithmetic expressions.

  ...

  Exit Status:
  If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.



أنه:

if [ $# -eq 0 ]
  then
    echo "No arguments supplied"
fi

سوف يخبرك المتغير $# عدد وسائط الإدخال التي تم تمرير النص البرمجي منها.

أو يمكنك معرفة ما إذا كانت الوسيطة عبارة عن سلسلة فارغة أم لا:

if [ -z "$1" ]
  then
    echo "No argument supplied"
fi

سوف اختبار -z اختبار إذا كان توسيع "$ 1" سلسلة فارغة أم لا. إذا كانت سلسلة فارغة ، فسيتم تنفيذ النص.




إذا كنت ترغب في التحقق مما إذا كانت الوسيطة موجودة أم لا ، يمكنك التحقق مما إذا كانت # من الوسيطات أكبر من أو تساوي رقم الوسيطة المستهدفة.

يوضح البرنامج النصي التالي كيف يعمل هذا

test.sh

#!/usr/bin/env bash

if [ $# -ge 3 ]
then
  echo script has at least 3 arguments
fi

ينتج الإخراج التالي

$ ./test.sh
~
$ ./test.sh 1
~
$ ./test.sh 1 2
~
$ ./test.sh 1 2 3
script has at least 3 arguments
$ ./test.sh 1 2 3 4
script has at least 3 arguments



نسخة متعددة الخيارات:

ask () {                        # $1=question $2=options
    # set REPLY
    # options: x=..|y=..
    while $(true); do
        printf '%s [%s] ' "$1" "$2"
        stty cbreak
        REPLY=$(dd if=/dev/tty bs=1 count=1 2> /dev/null)
        stty -cbreak
        test "$REPLY" != "$(printf '\n')" && printf '\n'
        (
            IFS='|'
            for o in $2; do
                if [ "$REPLY" = "${o%%=*}" ]; then
                    printf '\n'
                    break
                fi
            done
        ) | grep ^ > /dev/null && return
    done
}

مثال:

$ ask 'continue?' 'y=yes|n=no|m=maybe'
continue? [y=yes|n=no|m=maybe] g
continue? [y=yes|n=no|m=maybe] k
continue? [y=yes|n=no|m=maybe] y
$

سيقوم بتعيين REPLY إلى y (داخل البرنامج النصي).







bash shell