シェルスクリプトを使用してPython環境に入り、いくつかのPythonコマンドを実行して通常の端末に戻る方法

シェルスクリプトを使用してPython環境に入り、いくつかのPythonコマンドを実行して通常の端末に戻る方法

申し訳ありません。タイトルがはっきりしない場合があります。私の疑いの完全な説明は次のとおりです。以下のシェルスクリプトを作成しており、上記の出力を期待しています。

#!/bin/bash
python3
print("Hello World")
exit()
echo "The execution is completed"

私が期待する出力は、python3インタプリタに行き、コマンドを実行する必要があり、print手動exit()で実行するexit()と、コマンドを実行した後にインタプリタが終了してからコマンドを実行することですただし、実行後echoはそれほど機能しません。python3python3インタプリタを入力しましたがprint実行されませんexit()

>>>

python3に正しく入ってから、Pythonインタプリタを手動で終了するまでそのまま残ります。

予想される結果を得るにはどのような変更が必要ですか?

  1. 次の質問:Hello worldPythonインタプリタまたは他の出力から生成された出力をbash環境にインポートし、bashスクリプトで使用できますか? 2. pythonコマンドを実行するために指定した方法は他のツールでも機能しますか?

答え1

#!/bin/bash
python3
print("Hello World")
exit()
echo "The execution is completed"

スクリプトは、端末に直接コマンドを入力するのと同じようには機能しません。やりたいことが簡単にできません。

この#!/bin/bash行は、起動したいプログラムを使用する必要があることをカーネルに伝えます/bin/bash。したがって、カーネルを実行すると、bashは./scriptname標準入力ではなく標準入力(ターミナル)から/bin/bash ./scriptnameコマンドを読み込みます。scriptname

bashがこのpython行に達すると、Pythonインタプリタを起動し、次の行に進む前に終了するまで待ちます。 Pythonが起動すると、python端末に入力したときと同じことが行われ、対話型インタプリタが起動します。

Pythonはスクリプトファイルからコマンドを実行したいとは知らず、数行をスキップするように指示することもできません。
Pythonが終了すると、bashは次の行から続きます。quit()これは構文エラーであり、Bashに次の行をスキップするように指示することはできませんpython

Pythonにコマンドを実行させる方法は3つあります。

  1. Bashに区切られた文書(* 1)を介してPythonの入力にコマンドを作成させます。これにより、Pythonは端末からユーザー入力を読み取ることができません。
  2. -c短いコマンドのリストを提供するには、このオプションを使用します。これは非常に短いプログラムでのみ動作し(文字列の場合)、引用符を使用する必要はありません。複数のコマンドはセミコロンで区切ることができます。
  3. 2番目のファイルが必要な別のPythonスクリプトがあります。一時ファイル(* 2)に関連するセキュリティリスクを知っている場合は、必要に応じてbashにファイルを生成させることができます。ファイルを作成しないでください/tmp

次の質問:Hello world出力またはPythonインタプリタで生成された他の出力をbash環境にインポートし、bashスクリプトで使用できますか?

$(と を使用してコマンド置換を使用でき、)二重引用符で囲まれた文字列内で使用できます。次のように二重引用符で囲まれた文字列を入れ子にすることもできます。

test="$(python -c "import sys; print(sys.version)")"
echo "Python has finished"
echo "test = $test"

Pythonコマンドの実行を指定する方法は他のツールでも機能しますか?

上記の3つの方法はすべて、他の多くのスクリプト言語でも機能します。


* 1 Heredocの例

read -p "How many numbers: " n
python <<END
for i in range($n):
    print(i)
print("Literal dollar sign \$")
END

この<<END構文を使用すると、シェルは単語を読むまですべての行を読み取りますENDEND行の先頭になければなりません。

これにより、引用符をエスケープする必要がなくなります。シェルはまだドル記号を解釈するので、変数を使用できます。実際のドル記号が必要な場合は、次のようにエスケープする必要があります\$


* 2危険な一時ファイルの例。このコードを使用しないでください

cat >/tmp/python-script <<END
for i in range(10):
    print(i)
END
python /tmp/python-script

他の人が/tmp/python-script最初に作成した場合、ファイルを上書きできない限り、シェルスクリプトは停止しません。システムの悪意のあるユーザーが意図したスクリプトの代わりに実行される有害なPythonスクリプトを生成する可能性があります。

間違える可能性はそれだけではありません。

これを安全に行う方法はいくつかありますが、最も簡単な方法は現在の作業ディレクトリまたはホームディレクトリ内の専用ディレクトリにファイルを作成することです。

cat >dopythonstuff <<END
...
END
python dopythonstuff
rm dopythonstuff

答え2

Pythonを使用してbashスクリプトを起動し、変数をbashスクリプトに渡します。

Python変数の値をbashスクリプトに転送する(Pythonスクリプト内)

Pythonスクリプトでシェルコマンドを呼び出す方法に関するこのスタックオーバーフローの質問には62の答えがあります。

https://stackoverflow.com/questions/89228/how-to-call-an-external-command

Pythonを終了してからシェルコマンドを呼び出すことはできません。 Pythonスクリプトを終了する前にシェルコマンドを呼び出す必要があります。

https://www.geeksforgeeks.org/python-exit-commands-quit-exit-sys-exit-and-os-_exit/

上記のリンクの下のこの記事では、さまざまなコマンドを使用してPythonを終了する方法について説明します。

quit()、exit()、sys.exit() および os._exit() 関数は、スタックトレースを印刷せずに Python インタプリタが終了する SystemExit 例外を発生させるという点で、ほぼ同じ機能を持ちます。早期終了を傍受し、クリーンアップ活動を実行するために例外をキャッチできます。キャプチャしない場合、インタプリタは正常に終了します。

記事は次のように結論を下しました。

上記の4つの終了関数の中で、sys.exit()は本番コードでは使用できないため、sys.exit()が優先されますが、os._exit()は即時終了が必要な特別な場合にのみ適しています。

sys.exit("Exit message here")を使用してPythonスクリプトを終了し、コンソールに終了メッセージを作成してシェルプロンプトに戻ることができます。

関連情報