質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
cron

cronは、Unix系OS上でデーモンプロセスとして動作する、スクリプトの自動実行が可能なジョブスケジューラです。

シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1584閲覧

cron実行時にpythonプログラム中のシェルスクリプトの標準出力が受け取れない

popopo-v2

総合スコア1

cron

cronは、Unix系OS上でデーモンプロセスとして動作する、スクリプトの自動実行が可能なジョブスケジューラです。

シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/12/22 05:08

前提・実現したいこと

下記の構成でpython(venv)およびシェルスクリプトをcronで動作させようとしています。
手動では問題なく実行できますが、cronではsubprocess.runで実行したシェルスクリプトの結果が受け取れない状況で行き詰っています。
確認点などありましたら、どなたかご教示いただけますと幸いです。
(補足)
slappasswdでパスワードを入力後に標準出力される[{SSHA}SPciK5sfizFS*******************]のような文字列を取得し、
リストに追加したいと考えています。

発生している問題・エラーメッセージ

+ expect -c ' spawn slappasswd expect "New password:" send "文字列\n" expect "Re-enter new password:" send "文字列\n" interact ; ' spawn slappasswd New password: Re-enter new password: None None Traceback (most recent call last): File "/hoge/hoge1/pytools/test.py", line 5, in <module> get_ssha() File "/hoge/hoge1/pytools/test.py", line 14, in get_ssha ssha_list.append(m.group()) AttributeError: 'NoneType' object has no attribute 'group'

該当のソースコード

python

1ssha_list = [] 2def get_ssha(): 3 for i in range(len(df)): 4 pw = str(df.loc[i, 'pw']) 5 uid = str(df.loc[i, 'uid']) 6 proc_ssha = subprocess.run(['bash', '-x' ,'/hoge/hoge1/pytools/test.sh', pw, uid], stdout=PIPE) 7 proc_ssha_stdout = str(proc_ssha.stdout.decode('utf-8')) 8 #print(proc_ssha_stdout) #{SSHA}SPciK5sfizFS*******************]が表示されない 9 #print(re.search("{SSHA}.*", proc_ssha_stdout)) #None 10 m = re.search('{SSHA}.*', proc_ssha_stdout) 11 #print(m) #None 12 ssha_list.append(m.group()) 13get_ssha()

bash

1#!/bin/sh 2 3pw=$1 4uid=$2 5 6expect -c " 7spawn slappasswd 8expect \"New password:\" 9send \"${pw}\n\" 10expect \"Re-enter new password:\" 11send \"${pw}\n\" 12interact ;

試したこと

・cronの記載を変えてみる

0 0 * * * /hoge/hoge1/venv/bin/python /hoge/hoge1/pytools/test.py >> /hoge/hoge1/pytools/cron.log 2>&1 0 0 * * * cd /hoge/hoge1/pytools && /hoge/hoge1/venv/bin/python test.py >> /hoge/hoge1/pytools/cron.log 2>&1

・cronの指定をpythonではなくシェルスクリプトにする

bash

1#!/bin/sh 2PATH=/hoge/hoge1/venv/bin:/sbin:/bin:/usr/sbin:/usr/bin 3source /hoge/hoge1/venv/bin/activate 4python /hoge/hoge1/pytools/test.py 5deactivate

補足情報(FW/ツールのバージョンなど)

cronで実行時のみシェルスクリプトの結果が受け取れないため、エラーログでも「AttributeError: 'NoneType' object has no attribute 'group'」が出力されていると思われます。

proc_ssha = subprocess.run(['bash', '-x' ,'/hoge/hoge1/pytools/test.sh', pw, uid], stdout=PIPE) proc_ssha_stdout = str(proc_ssha.stdout.decode('utf-8')) #print(proc_ssha_stdout) #{SSHA}SPciK5sfizFS*******************]が表示されない

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2021/12/22 07:37

影響無さそうな気もしますが、expectにinteractが入っている意図は何ですか? また、expectを使わずパスワードをslappasswdのコマンドラインで指定すればいいのでは?
popopo-v2

2021/12/22 14:39

当初シェルスクリプトを作成していた際、slappasswd後の標準出力が受け取れず、interactを入れると受け取れたため、そのままにしておりました。 質問の説明が不足しており、非常に分かりずらく申し訳ございません。 確認したところ、cronで実行する場合はinteractのあるなしに関わらず受け取れないようです。 また、データフレームに「アカウント,pw等」の情報を格納し、順番にpwをexpectで自動入力させたいと考えておりました。
popopo-v2

2021/12/22 14:39

ご返答いただきありがとうございました。
otn

2021/12/22 15:25

expectを削除しても同じ現象だと言うことですね。 コードが途中で切れてしまっていますが、書いてない部分に問題がるのかも。
popopo-v2

2021/12/22 17:52

ご返答いただきありがとうございました。 ご回答いただいたにもかかわらず、理解できておらずすみません。 自分で調べきれず、expect以外の方法が分からなかったのですが、 これまでこのようなサイトで相談させていただいたことがなく、 にっちもさっちもいかず困っていたため、ご返答いただき非常に嬉しかったです。ありがとうございました!!
guest

回答1

0

ベストアンサー

expectのスクリプトの最後にinteractが入っていますね。 これが原因だと思います。

このinteracetはどんな目的で入っていますか?
手動の時には、ここで制御が戻るので通常のログインだとしたら、いろいろなコマンドが実行できるようになります
cronでは入出力の仮想端末が用意されないので、ちゃんと動けなくなります。。

ただ、slappasswdはshaを返して終了するので、まあ、このinteractに意味はなさそうではありますが。

単にinteractの行を消せば動くと思いますが、ちゃんとした処理にするのであれば、

shell

1expect eof 2exit

とか書いておけばいいのではいかと思います。

投稿2021/12/22 07:42

TakaiY

総合スコア13790

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

popopo-v2

2021/12/22 14:58 編集

ご返答いただきありがとうございました。 質問の説明が不足しており、非常に分かりずらく申し訳ございません。 下記対策を行った上で、python抜粋の下記をcron、手動で実行し表示させた場合、それぞれ下記のようになり、"stdout="の部分がcronだと1行目しか受け取れていないように見受けられることまで確認ができました。 手動で実行する場合、interactを消してしまうと、cronで実行した場合と同じ状況になってしまい、やはり1行目以降が受け取れないようです。 ■対策 --------------- ・interactを消す ・下記を追加する expect eof exit --------------- ■python抜粋 proc_ssha = subprocess.run(['bash', '-x' ,'/hoge/hoge1/pytools/test.sh', pw, uid], stdout=PIPE) print(proc_ssha) ★ proc_ssha_stdout = str(proc_ssha.stdout.decode('utf-8')) print(proc_ssha_stdout) ★ ■cronで実行した場合 ・print(proc_ssha) --------------- CompletedProcess(args=['bash', '-x', '/hoge/hoge1/pytools/test.sh', '文字列(pw)', '********(uid)'], returncode=0, stdout=b'spawn slappasswd\r\n') --------------- ・print(proc_ssha_stdout) --------------- spawn slappasswd --------------- ■手動で実行した場合 ・print(proc_ssha) --------------- CompletedProcess(args=['bash', '-x', '/hoge/hoge1/pytools/test.sh', '文字列(pw)', '********(uid)'], returncode=0, stdout=b'spawn slappasswd\r\nNew password: \r\nRe-enter new password: \r\n{SSHA}DbwPL6***************\r\n') --------------- ・print(proc_ssha_stdout) --------------- spawn slappasswd New password: Re-enter new password: {SSHA}DbwPL6*************** ---------------
popopo-v2

2021/12/22 18:04

重ねて投稿失礼いたします。 シェルスクリプトを下記のように修正し、(あまりよくないかもしれませんが)中間ファイルでテキスト出力させ、 そこからpythonで読み取らせることで一旦出力が読めるようになりました。 ・(追加)bash ---- expect \"{SSHA}.*\" #interact ; #削除 expect eof exit ---- コード自体全体的に見直しが必要ですが、 これまでこのようなサイトで相談させていただいたことがなく、 にっちもさっちもいかず困っていたため、ご返答いただき非常に嬉しかったです。ありがとうございました!!
TakaiY

2021/12/23 01:53

解決したようでよかったです。 回答には「interactを消すだけでよい」と書いてましたが、上記を見てそれではだめなのに気づきました。 expectほspownしたプロセスの出力をバッファして、期待する出力を待ちますが、待ちのコマンド(expect xxx)が無いと、そこで止ってしまいますね。 なので、 expect eof # spawnしたプロセスの終了待ち exit #expectの終了 は必須でした。
popopo-v2

2021/12/29 03:52

ご返答に気づけず遅れてしまいました。申し訳ございません。 >expectはspawnしたプロセスの出力をバッファして、期待する出力を待ちますが、 >待ちのコマンド(expect xxx)が無いと、そこで止ってしまいますね。 なるほど。。ご回答いただき、改めて挙動が少し理解できました。 ●●だから△△になるというような理解ができておらず、場当たり的に対応してしまっているため、 linuxやシェルスクリプトの造形(?正しいか分かりませんが…)を勉強しようと思います。 ご回答いただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問