「goto」と「labels」を置き換えるbashスクリプトを作成する方法

「goto」と「labels」を置き換えるbashスクリプトを作成する方法

一括:

@echo off
:step1
if exist "file1.txt" (GOTO step2) ELSE (GOTO X)
:step2
if exist "file2.txt" (GOTO Z) ELSE (GOTO Y)

:X
run the script from the beginning and file1.txt and file2.txt are created and the rest of the script is executed
:Y
run the commands to file1.txt and run the rest of the script
:Z
run the commands to file2.txt and run the rest of the script

私は「goto」と「tags」がbashには存在しないことを知っていますが、bashで上記と同様の操作を実行する他の方法は何ですか?

試み:

#!/bin/bash
if [ -e file1.txt ]; then
        echo "file1.txt ok"
            if [ -e file2.txt ]; then
                echo "file2.txt ok"
                alternative to goto label Z
            else
                alternative to goto label Y
            fi
    else
        echo "file1.txt doesn't exist"
        alternative to goto label X
fi

PD:アイデアを伝えるためにのみ使用される基本的なスクリプト

bashも実行する必要があるバッチ処理が実行する作業(混乱を避けるために重要です):

フルスクリプトはいくつかのコマンドを実行し、file1.txtとfile2.txtファイルを生成します。そのため、スクリプトが長くてある時点で中断される可能性があるので、中断された部分からスクリプトを起動したいと思います。検証の目的は次のとおりです。

  • file1.txtが存在する場合(Y)、スクリプトはそれをすでに作成しており、file2.txt(Z)が存在するかどうかを確認します(スクリプトの別の部分)。
  • file2.txt が存在すると (Z) そのポイントからコマンドが開始されるという意味です。
  • file2.txt(Z) は存在しないが file1.txt(Y) は存在する場合、 file1.txt(Y) と file2.txt(Z) の生成後に file1 start から始まる間にスクリプトが中断されたことを意味します。します。文字(例)
  • file1.txt(Y) と file2.txt(Z) の両方がない場合は、スクリプトの最初から始める必要があります (X)。

答え1

バッチスクリプトが何をすべきかを正確に知ったら、まずこれを少し単純化します。

@echo off
if exist "file1.txt" goto skip_part1
run the script from the beginning and file1.txt and file2.txt are created and the rest of the script is executed
:skip_part1
if exist "file2.txt" goto skip_part2
run the commands to file1.txt and run the rest of the script
:skip_part2
run the commands to file2.txt and run the rest of the script

次のように等しく作成できます。

@echo off
if not exist "file1.txt" (
  run the script from the beginning and file1.txt and file2.txt are created and the rest of the script is executed
)
if not exist "file2.txt" (
  run the commands to file1.txt and run the rest of the script
)
run the commands to file2.txt and run the rest of the script

これは次のbashスクリプトに直接変換できます。

#!/bin/bash
if [ ! -e file1.txt ]; then
  run the script from the beginning and file1.txt and file2.txt are created and the rest of the script is executed
fi
if [ ! -e file2.txt ]; then
  run the commands to file1.txt and run the rest of the script
fi
run the commands to file2.txt and run the rest of the script

答え2

奇妙に見えても、スクリプトはほぼ自動的に変換されます!ステップは次のとおりです

  1. スクリプトの先頭に挿入
_current_label="_first_state"
main_function(){
case "$_current_label" in
("_first_state")
  1. スクリプトの最後に追加
_current_state="_the_end"
return
;;
esac
}
while [ "$current_state" != "_the_end" ] ; do main_function ; done
  1. それぞれ:labelに変更されました。
_current_label="label"
;;
("label")
  1. それぞれgoto skip_part1に変更されました。
_current_label="skip_part1"
return

したがって、スクリプトは次のようになります

#!/bin/bash
_current_label="_first_state"
main_function(){
case "$_current_label" in
("_first_state")
_current_label="step1"
;;
("step1")
if [ -e file1.txt ]; then
        echo "file1.txt ok"
        _current_label="step2"
        return
else
        echo "file1.txt doesn't exist"
        _current_label="X"
        return
fi
_current_label="step2"
;;
("step2")
            if [ -e file2.txt ]; then
                echo "file2.txt ok"
                _current_label="Z"
                return
            else
                _current_label="Y"
                return
            fi
           _current_label="X"
;;
("X")
run the script from the beginning and file1.txt and file2.txt are created and the rest of the script is executed
_current_label="Y"
;;
("Y")
run the commands to file1.txt and run the rest of the script
_current_label="Z"
;;
("Z")
run the commands to file2.txt and run the rest of the script
_current_label=""
return
;;
esac
}
while [ "$current_label" != "" ] ; do main_function ; done

アイデアは非常に単純な有限状態マシンを構築することです。各状態は Case ステートメントのラベルです。各状態で、gotoソースコードでグローバル値を設定し、返すポイント_current_labelまたはラベルが表示されるまでコードを実行します。その後、ループはこの新しいラベルから始まり、Caseステートメントが再実行されるようにします。

「自動」翻訳は、決して実行できないいくつかのコードを入れます。

callこの「自動」翻訳はまたはステートメントを処理しませんstart

生成されたスクリプトをインデントできるツールがある場合は、実行することをお勧めします!

関連情報