このシェルスクリプト関数の意味は何ですか

このシェルスクリプト関数の意味は何ですか

誰かが私に、例えば各行の意味を教えてもらえますか?正規表現が使用される理由を理解していません。[!0122...]

#!/bin/sh
is_integer ()
{
    case "${1#[+-]}" in
        (*[!0123456789]*) return 1 ;;
        ('')              return 1 ;;
        (*)               return 0 ;;
    esac
}

ベストアンサー1

#!/bin/sh

シェル構文にコメントがあります。ただし#!、これはファイルが実行されたときにそのパスに格納されている/bin/shインタプリタを使用してファイルを解釈する必要があり、スクリプトへのパスを引数として実行する必要があることをカーネルに伝えます。

is_integer () compound-command

関数定義のためのPOSIX sh構文。

{
   ...
}

複合コマンド~と呼ばれるコマンドグループ。唯一の目的は、コマンドをグループ化して関数の本体にすることです。ここでは内容がただ一つなので重複しています。複合コマンドしかし、{ ... }コマンドグループを各関数の本文として使用するのが一般的で、コードを読みやすくするため、一般的にお勧めします。同じ関数を次のように書くことができます。

is_integer () case "${1#[+-]}" in
  (*[!0123456789]*) return 1 ;;
  ('')              return 1 ;;
  (*)               return 0 ;;
esac

case something in (pattern1 | pattern2) ...;; (pattern3)... ; esaccase/構造ですesac複合コマンド) はsomething各パターンを順番に一致させ、最初の一致で対応するコードを実行します。

これは。something${1#[-+]}パラメータ拡張、関数の最初の引数である引数に${param#pattern}演算子を適用します。1この演算子は、引数の内容の先頭からパターンに一致する最も短い文字列を削除します。または文字に一致するワイルドカードパターンです[-+](正規表現ではありません)。したがって、符号は削除された最初の引数の値に拡張されます。したがって、最初の引数があれば2になります。その場合は空の文字列になります。それでは、滞在してみてください。-+${1#[-+]}-2-22

引用されていることがわかります"${1#[+-]}"。通常、パラメータ拡張を引用する必要があります。それ以外の場合は、分割+グローブの影響を受けます。ここではこれが起こらない非常に少数のケースの1つです。

その後、この値はいくつかのパターンと一致します。

*[!0123456789]*is *- 任意の数の文字(ほとんどのシェルは非文字も受け入れますが) - の後に - ...または - 以外の任意の[!0123456789]文字の後に任意の数の文字(再)が続きます。したがって、10進数以外の文字(またはほとんどのシェルでは非文字)を含むすべての文字列と一致します。019*

一致するものがあれば、コードが実行され、関数がゼロ以外の数値であるかのように終了コードをreturn 1返します。1間違った/失敗する

''空の文字列を表す方法です。空の文字列も有効な数値ではありませんが、前のパターンと一致しません。

だから*何でも合わせてください。したがって、return 0前のパターンと一致しない文字列に対して実行されます。caseステートメントは関数の最後のコマンドであり、caseステートメントは次を返すため、ここでは重複します。成功/本物内部に実行コマンドがない場合。

したがって、ここで関数定義は次のように短縮できます。

is_integer() case ${1#[-+]} in
  ('' | *[!0123456789]*) false
esac

それはそれほど明確ではありませんが。

とにかく、そのコードを使用するのが正しいです[0123456789]。特に、入力検証の場合(シェル算術式で入力を使用するときに入力を検証することが重要です。シェル算術評価における整理されていないデータ使用のセキュリティ影響[0-9]または[[:digit:]]する必要がありますいいえsh具体的には、実装が0から9の範囲で並べられたすべての文字(または複数文字のソート要素)と一致する可能性があり、bash一部のBSDでは、0123456789英語システムの数だけでなく、すべての10進数の数字と一致する場合に特に使用できます。英語ロケールから。[0-9][[:digit:]]

たとえば、GNUシステムの一般的なアメリカ英語ロケール(現在のUTF-8を文字セットとして使用する傾向がある)のinはbash一致[0-9]します。

おすすめ記事