バッシュ理論

/bin/bash

0.インデックス

  1. ほとんどの人に起こること
  2. スクリプトの構造
  3. 画面に印刷
  4. ユーザー入力の読み取り
  5. bashでの計算
  6. 条件
  7. ループ
  8. 機能
  9. ゲップス

1.ほとんどの人に起こること

/ bin / bashまたは/ bin / sh

スクリプトを実行するときにマシンが最初に行うことのXNUMXつは、どのシェルでスクリプトを実行するかを確認することです。 現在のほとんどのLinuxシステム /bin/sh へのリンクです /bin/bash、ただし、これは常に当てはまるとは限りません。たとえば、 ビジーボックス 彼らは持って来る Sh そして通常彼らはまたもたらす Bash、ただし使用する場合 /bin/sh、Bashでは実行されません。 だから私はいつも使うことをお勧めします /bin/bash.

UnicodeとASCII

スクリプトで「¿」または「ñ」を使用できない理由を疑問に思ったことはありませんか? またはアクセントを使用しますか? インタラクティブなスクリプトでは非常に煩わしい場合があります。 これは、BashのデフォルトのエンコーディングがASCII、または同じ英語の文字セットであるためです。 これを変更するには、Unicodeを使用することをスクリプトに指示するだけです。 そのためには、コマンドインタープリターの直後に行を追加する必要があります。

#-*-エンコーディング:UTF-8-*-

この行がスクリプトの先頭にあることが重要です。

スクリプトを実行可能にする

«でスクリプトを実行する人の数はおかしいです$ bashscript.sh" の代わりに "$ ./script.sh'結局のところ、これは私たちがシェルを定義したものです。

実行権限を追加するには、以下を実行する必要があります。

sudo + x script.sh
スクリプトが実行可能である場合は、それをPATHに追加して、コンピューター上の任意の場所/フォルダーから実行可能にすることができます。 そのためには、ユーザーの.bashrcまたは/ etc / bashrcに行を追加する必要があります。
BIN = "スクリプトがあるフォルダー" PATH = "$ BIN $ PATH"
変数名をすべて大文字で書くのはBashのルールです。 多くの人はこのルールに従わないが、長いスクリプトの場合は、スクリプトがはるかに読みやすくなるため、高く評価されている

2.スクリプトの構造

  1. ヘッドボード
  2. グローバル変数の定義
  3. お問い合わせ
  4. 機能
  5. 本体

ヘッダーは、使用するシェルとエンコーディングを示す場所です。 この関数の利点は、100回だけ記述して繰り返されるコードを再利用し、スクリプトを理解しやすくすることです。XNUMX行を超えるコードの場合は非常に便利です。

関数を使用するには、スクリプトの本体の前に関数を定義する必要があります。 また、本体と関数の両方で、すべてのスクリプトのグローバルレベルで変数を使用する場合は、すべての先頭、ヘッダーの直後に変数を定義する必要があります。

最後に、スクリプトが正しく実行されない場合やパラメーターが正しくない場合に備えて、ヘルパー関数を作成することをお勧めします。 明らかに、そのような場合は、関数を読まずにスクリプトをすぐに終了したいと思います。 そのために使用できます:

function help(){echo "" "適切にフォーマットされたヘルプテキスト。" "" exit if [[-z $ 1 || $ 1 == "-h" || $ 1 == "--help"]]; その後、fiを助けます

ヘルプ関数に「exit」を追加すると、たとえばエラーメッセージの後など、ヘルプを実行するたびにスクリプトが終了します。 数行のコードを保存します。

この条件は、スクリプトがパラメーターなしで実行された場合、または-h / –helpが指定された場合に、画面にヘルプを表示して終了することを示します。 あなたが見ると、それはほとんどのLinuxプログラムの標準的な動作です。

echoで3つの引用符を使用すると、echoで表示されるメッセージを残さずに改行を使用できます。 複数行のメッセージの場合、エコーをXNUMX回だけ使用する方がはるかに便利です。

3.画面に印刷する

bashで画面に印刷するための2つの主なコマンドがあります:«echo"Y"printf«。 それらは両方とも同じくらい速く、両方ともbashの一部です。 初心者にとっての主な違いは、エコーが最後に新しい行を追加するのに対し、«printf"ではない。

エコーは問題なく、ほとんどの人が使用しますが、ユーザーのINPUTを読み取るとき、またはワード処理によってファイルから取得した変数を印刷するときは、奇妙なことが起こる可能性があります。 これらは通常、二重引用符を一重引用符に変更したり、その逆に変更したり、引用符から変数参照を削除したりするのと同じくらい簡単に解決できます。 «Echo»コンパイル方法によっても奇妙なことをします。常にUbuntuまたは常にFedoraを使用している場合は影響しませんが、ディストリビューションを変更した場合は影響します。

だから私は«を使用しますprintf«、これは私に頭痛の種を与えず、また«のように振る舞いますprintf»Cまたは«から印刷»Python、これは、スクリプトを別のプログラミング言語に移植する場合に非常に重要です。

より広範な議論については、あなたが訪問することができます StackExchange上のUnixとLinuxからのこの質問.

4.ユーザー入力を読み取ります

スクリプト名の後、ENTERキーを押す前に書き込んだものはすべて、特別な変数に自動的に保存されます。 これらの変数のタイプは$ Xで、Xは数値です。

«$0»スクリプトの名前とfrom«を示します$1»無限に、後で書いたものはすべて可変です。 例えば:

cat << EOF >> test.sh#!/ bin / bash#-* --ENCODING:UTF-8- * --printf "\ $ 0 = $ 0 \ n" printf "\ $ 1 = $ 1 \ n" printf "\ $ 2 = $ 2 \ n "EOF chmod + x script.sh ./script.sh my file.txt

テストスクリプトを作成して実行可能にし、2つのパラメーターを使用して実行します。 次の画面出力を取得します。

$ 0 = ./script.sh $ 1 =私の$ 2 = file.txt

引用符を使用すると、「myfile.txt」を「$ 1」に渡すことができます。

「read」コマンドを使用してユーザーのINPUTを読み取ることもできます。これは、パラメーターを保存する変数を直接示します。 例えば:

printf "あなたの名前は何ですか?\ n" read NAME printf "こんにちは、$ NAME。\ n"
変数の割り当てには注意してください。 「$ VAR = content」はエラーを生成します。等号、変数名、およびコンテンツの間にスペースを残すことはできません。 正しい使用法は「VAR =コンテンツ」です

5.バッシュでの計算

そのために«を使用できます«複雑な計算を行う必要がない限り。 XNUMXつのことに注意する必要があります。XNUMXつ目は«»整数のみを許可します。XNUMXつ目は、除算が結果全体を返し、残りを使用できることを確認することです«%"

通常、exprの結果を変数に割り当てたいと思うでしょう。 これはXNUMXつの方法で実行できます。

VAR2 = `expr $ VAR1 / 10` VAR2 = $(expr $ VAR1 / 100)

スキップすることもできます«»二重括弧の使用:

VAR2 = $(($ VAR1 / 100))
«の詳細については»または整数を使用する代替案は、 このKZKG ^我愛羅エントリー.

6 条件

それはすでに«について非常に広範囲に書かれていますif«、«ほかに«、«elif»そして条件。 あなたはそれについて読むことができます:

単純な角括弧の使用の違いを強調したいだけです、«[]«、および二重括弧、«[[]]«、条件について。 二重括弧を使用すると、追加の条件を使用できます。

  • «&&»および
  • «||»または

使用するには&&"Y"||»単純な角括弧では、各部分を別々の角括弧で区切る必要があります。 ヘルプを実行する必要があるかどうかを確認するスクリプトの部分に使用される例は次のとおりです。

if [-z "$ 1"] || ["$ 1" == "-h"] || ["$ 1" == "-help"]]; その後、fiを助けます

また、エラーを防ぐために変数名を引用符で囲む必要がなくなります。 例えば:

if [$ 1 = 1]; 次にprintf "パラメータは1に等しい。"; fi if ["$ 1" = 1]; 次にprintf "パラメータは1に等しい。"; fi if [[$ 1 = 1]]; 次にprintf "パラメータは1に等しい。"; fi

script.shをパラメーターなしで実行すると、最初のケースでエラーが発生します。

bash:[:=:unary演算子が必要です
バッシュでは、「=」と「==」はどちらも同じように解釈されます。 これは、「=」が変数の割り当てにのみ使用される他のプログラミング言語では発生しません。

議論されていないのは«場合«、これは単純化するために使用されます«if«。 «がない最初から始めましょうif»すべてのコードが実行されます。 条件を追加すると«if»XNUMXつのケースがあります。XNUMXつは、«内にあるコードのブロックです。if»そして、このブロックが実行されない他のケース。

«を追加するとほかに«XNUMXつのケースもありますが、これらXNUMXつのケースは前のケースとは異なります。 これで、AとBのXNUMXつの条件付きコードブロックと、プログラムの残りの部分であるCブロックが存在するためです。 AまたはBが実行され、Cが実行されます。前のケースでは、AとC、またはCのみでした。

書き込み条件を避けるために«if / else" 以内に "ほかに»そして、コードの読み取りを簡素化するために、それが作成されました«elif«。 数値の範囲やタイプなど、前の条件に依存する条件が多数ある場合:

VAR1 = $ 1 if [[$ VAR1 = 1]]; 次にprintf "1 \ n" elif [[$ VAR1 = 2]]; 次に、printf "2 \ n" elif [[$ VAR1 = 3]]; 次にprintf "3 \ n" else printf "none \ n" fi

最後の場合«elif»多くの条件が読み取られます。 場合によっては、このプロセスは合理化されます。

VAR1 = $ 1ケース$ VAR in 1)printf "1 \ n" ;; 2)printf "2 \ n" ;; 3 | 4)printf "3または4、依存します\ n" ;; *)printf "none \ n" ;; そのC

変数(この場合はVAR1)が読み取られ、いずれかのケースと同等であるかどうかが確認されます。同等でない場合は、デフォルトのケース「*」が実行されます。 ダブルセミコロンは«と同等です破る«、彼らは言う«場合»それは終わらせなければなりません。

«シミュレーション例»一連の«としても使用できますif«、そのためには、«;;»の代わりに«;;&»(続行)を使用する必要があります。 (やめる)。

7.ループ

どのプログラミング言語でも、既知のループはほとんどありません。 バッシュでは、彼らは«while«、«まで"Y"for«。 これらについてはすでにブログに書かれています:

ループにはXNUMXつのタイプがあります«for«、タイプのもの«LOQUESEAのVARの$»そしてタイプCは何ですか«$ for((I = 0; I <= 10; I ++))«。 XNUMX番目のタイプのループ«for»非常に便利です。ループの最初に3つの部分があります。

  • 変数の宣言と開始(この場合、補助変数 "I = 0")。
  • 実行条件(Iが10以下になるまで)。
  • 補助変数の増加

私の意見では、それはすべての中で最も強力なループです。 0から10までのすべての数値を出力する例:

#!/ bin / bash for((I = 0; I <= 10; I ++)); printf "$ I \ n"を実行します

8.機能

バッシュが私たちに許可していないことがいくつかありますよね? 一見したところ、bash関数を使用すると、関数内でローカル変数を宣言する、関数にパラメーターを渡す、パラメーターを返すという3つのことを実行できなくなります。 すべてに解決策があります。

次のようなことは何もしません。

#!/ bin / bash VAR = 1 printc "$ VAR \ n" function hello(){VAR = 2 printf "$ VAR \ n"} hello printf "$ VAR \ n"

これは、画面1、2、および2に出力されます。

ローカル変数を宣言するには、«を追加しますローカル»宣言する場合:

#!/ bin / bash VAR = 1 printf "$ VAR1 \ n" function foo(){local VAR1 = 2 printf "$ VAR1 \ n"} printf "$ VAR1 \ n" foo printf "$ VAR1 \ n"

これにより、1、1、2、1が画面に印刷されます。

関数にパラメーターを渡すにはどうすればよいですか?

#!/ bin / bash#-* --ENCODING:UTF-8- * --function hello(){printf "Hello $ 1 \ n"}

printf "あなたの名前は?\ n"
VAR1を読む
こんにちは$ VAR1

パラメータはどのように返されますか?

#!/ bin / bash#-* --ENCODING:UTF-8- * --function hello(){printf "Hello holita"} printf "What's your name?\ n" read VAR1 VAR1 = $(hello)#ここにありますprintf "$ VAR1 $ VAR2 \ n"

ご覧のとおり、これにはXNUMXつの欠点があります。XNUMXつのパラメーターしか返すことができず、ベクトルになる可能性があります😀。パラメーターを返したい場合は、その関数から画面に印刷できなくなります。

関数の詳細については、[url=https://blog.desdelinux.net/programando-en-bash-parte-3/]Usemoslinux のこの記事[/url]。

9. ゲトプス

複雑なスクリプトを作成するためにBashについて知っておく必要がある最後のことのXNUMXつは«ゲトップス«。 順序に関係なく、スクリプトにオプションを渡すために使用されます。 唯一の欠点は、短いオプションにのみ影響することです。

#!/ bin / bash#-* --ENCODING:UTF-8- * --VARC = 0 function help(){printf "Help message \ n" exit} if [[-z $ 1]]; 次に、getopts中にfiを支援します。ha:b:c OPT; h)ヘルプでケース$ OPTを実行します;; :) 助けて ;; a)VARA = $ OPTARG ;; b)VARB = $ OPTARG ;; c)VARC = 1 ;; \?) 助けて ;; esac done#VARA、VARB、VARCで処理を行うスクリプトのメインブロック

«getopts»オプションをXNUMXつずつ読み取るため、ループが必要です。

«を使用して渡すことができるオプションには2つのタイプがあります取得「:

  • フラグと呼ばれるパラメーター。この場合は-cまたは-hです。 それらは私たちが使いたい文字で指定されています。 それらはブール変数のようなものです、«true»(are)または«false「(彼らはここにいない)。
  • 関連付けられた引数を持つパラメーター、-a any、-banything。 それらは、下にコロンを付けて必要な文字で指定されます。 引数はOPTARGに保存されます(この名前は変更できません)。
最初の二重のポイントは、エラーがないことを示すことです。

このスクリプトは何をしますか?

オプションが渡されなかった場合、「-h」パラメータが渡された場合、無効なパラメータが渡された場合(たとえば、「-x」、これは「\?」によって実行されます)、または引数のない有効なパラメーター( ":")。 残りの場合、VARCでは「-c」の存在を1として保存し、VARAとVARBでは「-a」と「-b」で渡された値を保存します。


コメントを残す

あなたのメールアドレスが公開されることはありません。 必須フィールドには付いています *

*

*

  1. データの責任者:MiguelÁngelGatón
  2. データの目的:SPAMの制御、コメント管理。
  3. 正当化:あなたの同意
  4. データの伝達:法的義務がある場合を除き、データが第三者に伝達されることはありません。
  5. データストレージ:Occentus Networks(EU)がホストするデータベース
  6. 権利:いつでも情報を制限、回復、削除できます。

  1.   エラヴ

    見事に。 これ以上は言いませんU_U

  2.   ミゲル

    こんにちは、とても良い記事です。
    許可を与えるために chmod +x の代わりに sudo +x を入力しました

    1.    ヘンリー

      $ sudo chmod +x script.sh
      (正確に言うと、ふふ)

      ああ、おめでとう、そしてありがとう!

  3.   ファイヤーコールド

    とても良い投稿です。本当におめでとうございます。頑張ってください。よろしくお願いします

  4.   グスタボ

    また、スクリプトの実行時にスクリプトを段階的に表示して、変数、条件、その他すべてがどのように動作するかを確認したい場合は、次のコマンドを使用できます。

    sh -x スクリプト

    よろしく

  5.   ダゴ

    チュートリアルの一部。 素晴らしく、とてもよく説明されています。
    ありがとう。

  6.   ガブリエル

    このテーマに関する素晴らしい投稿です 😉

  7.   マリオギレルモザヴァラシルバ

    非常に興味深く、非常に重要な情報をありがとうございます…。
    乾杯!!!

  8.   ブルックリン以外

    おめでとうございます。Miguel コマンドに関しては、一度公開するとエントリを変更することができません。 エラフはそれをやらなければならないだろうと私は想像している。

  9.   エイドリアン

    とても良いです。

    まず最初に、この投稿を祝福したいと思いました。これは理解しやすく、特にプログラミングを始めようとしている人にとって、bash で適切にプログラムするためのガイドラインに従うのに非常に役立ちます。

    ただし、修正する必要があると思われる詳細がいくつか見つかりました。

    まず、セクション«2. スクリプトの構造» 関数は閉じられていないため、スクリプト内で実行するときに問題が発生します。
    解決策は、「exit」コマンドの直後に右中括弧を追加することです。

    4 番目: セクション«0。 READ USER INPUT」では、ユーザーが入力できるパラメータの範囲は $0 から無限大であると述べていますが、$9 は $10 + 1 に等しいため、「bash」は $0 から $XNUMX のみを解釈します。
    この問題を解決するには、「shift」コマンドを使用して次の変数を取得します。 または、変数を中括弧 "${10}" で囲み、bash が $1 + 0 ではなく値をまとめて取得するようにします。

    早速ですが、ご挨拶申し上げます。

    1.    ブルックリン以外

      ご意見ありがとうございます。 スクリプトと関数の両方での exit の正しい使用法を説明するのを完全に忘れていました。 ${10} については、私はそこまで到達したことがなかったので、その問題には遭遇していませんが、その解決策があることを知って良かったです (今日学んだ新しいことにはすでに取り消し線を引いています 😀 )。

  10.   チャニオ

    記事をありがとうございました! あなたが言及したいくつかのことは、私が明確にする必要がありました。 たとえば、ゲトップス。
    画面上の出力の部分で、後で言及する猫について言及し損ねていました...
    猫<
    ***************************************
    *この形はとても表現力豊かです*
    ***************************************
    EOF

    あなたの例では:
    cat << EOF >> test.sh
    言及すべきことが XNUMX つあります... >> それは「追加」です。つまり、同じコマンドを繰り返すと、スクリプト全体が XNUMX 回作成されます... 使用するのは XNUMX つだけです...
    cat << EOF > script.sh
    はい、script.sh という名前にする必要もあります。
    その後、
    if [ -z "$1" ] || [ "$1" == "-h" ] || [ "$1" == "--ヘルプ" ]]; それから
    助けます
    fi

    書いておくべきだと思うのですが…
    if [[ -z "$1" ] || [ "$1" == "-h" ] || [ "$1" == "--ヘルプ" ]]; それから
    ...

    BASH 以外にも発見すべきことがたくさんあります。
    「BASICS」というタイトルを付けていただけますか? 🙂
    たとえば、パラメータ「testers」は、空かどうかを知るには -z のように、ファイルとして存在するかどうかを知るには -f のようにします。

    改めて、ご尽力いただきありがとうございます。
    アルベルト

  11.   クロウエリオール

    非常に優れた bash スクリプトのチュートリアルです。

  12.   ocz

    -エンコード:UTF-8-

    bash スクリプトで文字エンコーディングを設定するこのような行を見たのは初めてです。 私には Bash よりも Python に似ているように思えます。 本当に必要なのでしょうか? Google で参考資料を探しましたが何も見つかりません。この件について説明しているリンクは手元にありますか? 特にそのラインの適合性について。

    私の意見では、UTF-8 を使用して Bash スクリプトを作成するには、テキスト ファイルをそのまま (BOM なしで) 保存し、特定の環境変数 (LANG と LC_*) を正しく設定するだけで済みます。
    その場合、当然ながら、実行されるコマンドは ASCII 以外のエンコーディングに対応するように準備されている必要があります。 たとえば、大文字に切り替えたい場合、これは機能しないようです。
    «エコー・アエィオウ | トラズ AZ»
    o:
    «エコー・アエィオウ | tr [:下:] [:上:]”
    そして、以下を使用することをお勧めします。
    «エコー・アエィオウ | awk '{ print toupper($0) }'”。

    1.    ブルックリン以外

      « についてのことエンコーディング» 以前このブログで言及しました:

      Bash: スクリプトを実行可能にする方法
      インストール後のユーティリティ スクリプト

    2.    ボリキトコモツ

      誰かが私を訂正してくださいましたが、そのコード行 (# --エンコード:UTF-8--) これは bash やシェルとは何の関係もありません。これはコメント行 (# で始まります) であり、スクリプト (vim、emacs など) を記述するために使用するファイルのエンコーディングをエディターに伝えるために使用されます。

      実際、bash はその行を認識しません。これはコメント行であるためです。

  13.   ジョルゲ-1987

    優れたチュートリアル。Bash でスクリプトを作成する方法をシステム管理者が知っていることが不可欠なので、あらゆる面で役に立ちます。

    とてもとても良いです!

    ご挨拶!

  14.   エドゥアルド・クオモ

    誰かの役に立つ場合に備えて、独自のスクリプトを作成するためのいくつかの使用法と例を以下に示します。 https://github.com/reduardo7/hsabx

  15.   リトブラック

    とても良い。 スクリプトに新しいものを追加します。 encode と printf にはそれがありませんでした。
    ありがとう!!!

  16.   xxxtonixxx

    とても良い記事です! これをお気に入りに保存しています。間違っている点を修正し、より多くのコンテンツを追加して拡張することもできれば幸いです。 このすべての情報に拍手を送ります!!!!