実行中のスクリプトは自分でバックグラウンドに移動できますか?
私は目的があります: 私はスクリプトを実行します: ./script.sh
。スクリプトでパスワードを要求します。
echo -n PASSWORD:
read -s pass
if [ "${scriptPassword}" == "$pass" ] && [[ ${pass_counter} = 0 ]]; then
pass_counter = $ ((pass_counter + 1))
echo "PASSWORD OK"
Ctrl次に+を押してからコマンドを実行するのとZ
同じ効果を得たいと思いますbg
。スクリプトからこれらのコマンドを実行できますか?
スクリプトが で始まったかのように機能したいのです
nohup ./script.sh &
が、ユーザーが正しいパスワードを入力した後にのみ可能です。
答え1
1. 直接法
これは次のように似ています。ホクラキンの答えしかし、もっと簡単です。スクリプトがインタラクティブな操作を完了したら、次の手順を実行します。
(kill -STOP $$; kill -CONT $$) &
sleep 1
ここで、スクリプトは+Ctrlに非常に似ている非常に小さい(非同期)サブシェルを作成してそれを停止(スクリプトプロセス)してから、次のようにZします。続く実際の信号と非常によく似た直感的な信号bg
。その必要さえないかもしれませんsleep
。シグナルが入ってくると、スクリプトが重要なタスクを実行しない方が安全であると思います。
私はこれをテストしましたが、表面的にのみテストしたので、実際のアプリケーションコンテキストで使用すると驚くことがあります。
____________
*違いはCtrl+ ZSIGTSTP 転送です。スクリプトで SIGSTOP の代わりに SIGTSTP を使用できます。 SIGSTOPでテストしましたが、うまくいけば変更する理由はありません。
2. おそらくもっと簡単でしょう(おそらくより移植性が高いでしょうか?)
スクリプトに自分自身を非同期的に呼び出すようにします。
if [ "$exported_pass" != "$scriptPassword" ] それから [読むには、ここに適切なコードを挿入してください。渡すユーザーとループで] [適切になるまで(または試しすぎてやめます)。 ] # だからこの時は "$scriptPassword" == "$pass" エクスポートしたパス = "$passes" エクスポートエクスポート_パス いいえ "$0" "$@" & 出口 フィリピン諸島
スクリプトが最初に実行されたときに$exported_pass
設定されていないため、入力してif
パスワードthen
を求めます。その後、それをexported_pass
環境変数に入れて自分自身を非同期で呼び出します。その後、基本(親)プロセスが終了します。スクリプトへの2回目の呼び出しはバックグラウンドで実行され、環境でパスワードを確認した後に操作を続行します。
答え2
スクリプトを実行できるように、スクリプトを実行する前に親シェルにトラップを設定できますbg
。問題は、スクリプトの実行時にトラップが実行されないことです。
ターミナルがスクリプトSIGSTOP
に送信された後(その後、親シェルが再び制御権を持つ)トリックは、スクリプトにこの操作を自分で実行させることです。
# preparation in the parent shell
trap 'bg %%' USR1
スクリプト:
#! /bin/bash
# parent shell has executed: trap 'bg %%' USR1
# pass or determine this value
PARENT_SHELL_PID=5646
read -p "enter value: " input
kill -USR1 $PARENT_SHELL_PID # execution of this in parent shell is delayed
kill -STOP $$ # returns control to parent shell
sleep 1000
ラッパースクリプトを探しています。
2つのスクリプトをインポートしてそれらのうちの1つを取得できる場合は簡単です(つまり、サブシェルではなく現在のシェルのコンテキストで実行されます)。
ラッパースクリプト:
PARENT_SHELL_PID=$$ ./script.sh
bg %%
実際のスクリプト:
#! /bin/bash
test -z "$PARENT_SHELL_PID" && exit 2
read -p "enter value: " input
# return control to sourced wrapper script
kill -STOP $$
# continue in the background
sleep 1000
両方実行
. wrapper.sh
答え3
可能ですか?移動するバックグラウンドシェル用のスクリプトを実行していますか?
「モバイル」という言葉を使うと混乱します。あなたはおそらく他の動詞に言及しているでしょう(どの動詞であるかを推測することはできません)。私はそれを文字通り受け入れます...
ㅏシェルスクリプトたった一つだけ文書(そしてプロセススクリプトを解釈するには、次のようにします。一部プロセスまたはスクリプトを実行するかどうか)。移動できます(使用してmv(1)
または使用名前変更(2)一部のプログラムでは)実行中。しかし、それを解釈するシェルはいくつかを開きました。ファイル記述子それはすべて、何も変わりません。実際、あなたはスクリプトを移動したくありません。(プロセスや作業は移動できませんが、ファイルは移動できます。)「移動」動詞は非常に混乱しており(少なくとも私には英語が母国語ではありません)、あなたが本当に欲しいものが何であるか、その理由が何であるかを理解できません。 。
(もう一つの問題は書くスクリプトの実行中はこれについて尋ねません)
いくつかのプログラムが(偽)端末の内部でユーザーの動作を模倣したいと思います。読むttyが公開されましたページ(ターミナルと擬似端末は非常に複雑で、詳細を忘れてしまいました)。使用予想される端末内でユーザーを偽装します。
しかし、スクリプトでパスワードを管理するのは危険です(セキュリティの脆弱性作りもとっても簡単で)間違いがしやすいので臭いがとても不快です。たとえば、ssh
公開鍵と秘密鍵を使用してこれを防止したいとします。
そのため、(スクリプト内で)パスワードが自動的に提供されないようにシステム全体を再設計することをお勧めします。
明らかにこれをやりたいと思います(ただし、端末で直接実行するのか、それとも別のスクリプト内で実行するのかわかりません)。
CTRL+Z
bg %%
これはおおよそ職業管理。バックグラウンドで実行されるのは、シェルまたはスクリプトを解釈する他の一般的な実行可能プログラムを実行するプロセスであるという事実は不適切です。Unixシェルカーネルの観点から見ると、これは通常のプログラムです。 IIRC、職務管理対。プロセスグループ。
コメントで特定のデータベースに接続すると言われました。最大リレーショナルデータベース管理システムクライアントプログラムは、より適切な方法でパスワードを提供する方法を提供します(おそらく--login-path
mysql
コマンド用)。他のスクリプトでこれを行う場合ここのドキュメント楽になるかもしれません(ここのドキュメント一部のSQLコマンドを含めたり合成したりできます。また、RDBMSシステムは、認証が失敗してもデータベースを変更しないことに注意してください。
スクリプトからこれらのコマンドを実行できますか?
bg %%
スクリプトでどのコマンドを実行したいかわかりません(はい)。スクリプトでジョブ制御を実行したい場合(ただし、そうしてはいけないと思います)、これがexpect
より適切かもしれません。
スクリプトが機能したいのです
nohup ./scripts.sh &
が、正しいパスワードを入力した後にのみ可能です。
その編集者私を混乱させるでも。どのパスワードについて話していますか(あなたのスクリプトが一部のRDBMSサーバーにパスワードを提供しているのか、完全に機能するためにパスワードが必要なのかわかりません)。私の考えではデータベース関連のタスク(たとえば、数時間持続するバックアップ)を実行するいくつかの長期実行スクリプトがあります。その場合は、別の質問をする必要があります。たとえば、(対話形式で入力された)パスワードをどこかに保存してから一括バックアップを実行できます(おそらく以下を使用して)。batch
少し注文してくださいここのドキュメント)。ただし、さまざまなRDBMSにはパスワードを提供して認証を行う方法が異なるため、今後の質問で使用している実際のRDBMSに言及する必要があります。
したがって、より多くの動機を与え、より多くの文脈を提供するように質問を改善することを検討してください。ただ推測だけで間違っているかもしれません!
または、次のようなことをしたいかもしれません。デーモン(3)あなたの殻に?これは別の質問を提起します(bashフリーソフトウェア、いつでもパッチを適用して新しいアイテムを追加できます。組み込み内部)。と思います(でも全然わからない)exec
シェル組み込みが便利です。