※初心者がハマっていく過程が長文で書いてありますので、
お急ぎの方は下部の自己解決の回答を先にお読みください。
初心者です。
###参考URL1
phpとpython連携で実行ユーザーの違いではまった件
https://tsukarooohi.com/416.html#phppython
こちらの方と同様の症状ではまっています。
###参考URL2
下記のURLも該当するかどうか、只今検証中です。
【AWS CLI】PHPのexec();を使うとAWS CLIのcredentialsがnot foundになるときの対処方法
https://note.com/garugarion/n/n42c6f24dc892
実現したい事:
PHPからPythonファイルを実行。Amazon CLIからpollyを使って、公開状態でS3に音声ファイルを生成したい。
###環境
SAKURA VPS CENTOS7 Python3.5
前提:
コマンドラインから
/usr/lib/python3.5/フルPATH/polly.py
を実行すると、何の問題もなくPollyを実行できる。
S3に音声ファイル生成も出来る。
aws s3api put-object-acl --bucket bucket_name --acl public-read key path
等として、(後から)公開状態にする事も出来る。
しかし、
1.WEBブラウザ上から、全く同じPYTHONファイルを、
2.<?php exec("python /usr/lib/python3.5/フルPATH/polly.py"); ?>にて実行
という実行経路にした瞬間、動作しない。
0777のファイル権限、chownやchgrpといった問題ではない。
####1:sudo visudoで、分からないなりに、下記の行を全部追記して、apacheを再起動した。NGだった。
root ALL=(ALL) ALL apache ALL=(ALL) ALL root ALL=(ALL) NOPASSWD: ALL apache ALL=(ALL) NOPASSWD: ALL www-data ALL=(ALL) NOPASSWD: ALL www-data ALL=(ALL) NOPASSWD: /usr/bin/python /usr/lib/python3.5/site-packages/polly/a.py www-data ALL=(ALL) NOPASSWD: /usr/bin/python /usr/lib/python3.5/site-packages/polly/polly.py www-data ALL=(ALL) NOPASSWD: /usr/bin/python /usr/lib/python3.5/site-packages/polly/polly2.py %www-data ALL=(ALL) NOPASSWD: /usr/bin/python /usr/lib/python3.5/site-packages/polly/polly2.py %www-data ALL=(ALL) NOPASSWD: /usr/bin/python /usr/lib/python3.5/site-packages/polly/polly.py %www-data ALL=(ALL) NOPASSWD: /usr/bin/python /usr/lib/python3.5/site-packages/polly/a.py %www-data ALL=(ALL) NOPASSWD: ALL %www-data ALL=(ALL) NOPASSWD: /usr/bin/python3 /usr/lib/python3.5/site-packages/polly/a.py www-data ALL=(ALL) ALL
2:CLIではなく、コード上にAWSのsecret access keyを記述して音声ファイルを出力すれば動く。
出力先が/var/www/html/だったので、公開非公開のコントロールも容易にできた。
3:AMAZON POLLYは1500文字以上はCLI経由で実行しないといけないため、どうしてもCLIにする必要があるため、その他、『Python 環境変数とは?』等と検索しながら概念を理解しようと試みた。
NGだった。
今日も又、朝から16時間以上1個のバグで消耗。これまでに、同様の
『PHPとPython間のユーザー権限の連携がうまくいってない。』
『rootとapacheがこんがらがってファイル生成ができなくなる』
という症状で、かれこれ40時間以上を無駄にしてきました。
###PHP側
polly.php
1<?php 2//putenv('USER=apache'); 3echo get_current_user(); // -> root 4 5$polly='Hello world.'; 6 7$tmp2=exec("python /usr/lib/python3.5/site-packages/youtube_transcript_api/polly.py $polly"); 8echo $tmp2; 9?>
※python側のシバンに
シャープ!/usr/bin/python3.5
と書いてあるので、
exec("python {$pythonに渡す環境変数(/usr/bin/python3.5/ ?)} /usr/lib/python3.5/フルPATH/polly.py");
と書いてもexecの文法が間違っているのか、NG。
冒頭のURL
https://tsukarooohi.com/416.html#phppython
の方は、.shファイルから環境変数(や実行ユーザー)をpythonに渡して動かしているようなのですが、関連情報を検索したところ.shの文法は未知の言語で記述されていて断念しました。
###PYTHON側
#!/usr/bin/python3.5 #coding:utf8 # -*- coding: utf-8 -*- from boto3 import Session from boto3 import resource import boto3 from contextlib import closing import itertools import os import sys import subprocess from pathlib import Path polly = sys.argv[1] speech = 'aws polly start-speech-synthesis-task --region us-west-1 --endpoint-url "https://polly.us-west-1.amazonaws.com/" --output-format mp3 --output-s3-bucket-name bucket-name --voice-id Justin --text "'+format(polly)+'"' out = subprocess.check_output(speech, shell=True) out = out.decode('utf-8') import json data = json.loads(out) print(data['SynthesisTask']['OutputUri']) soundurl=data['SynthesisTask']['OutputUri'] import time time.sleep(10) publicread = 'aws s3api put-object-acl --bucket bucket-name --key '+soundurl+' --acl public-read' out2 = subprocess.call(publicread, shell=True) new_dir_path4 = '/var/www/html/t4/' if not os.path.exists(new_dir_path4): os.mkdir(new_dir_path4) file4 = '/var/www/html/t4/hello.txt' Path(file4).touch() with open(file4,'w', encoding='utf8') as f: print(soundurl, file=f)
※aws configure --profile hoge
から別のAWSアクセスキーを試してみたのですが、NGでした。
AWS関係なく、rootとapacheのユーザーの違いを乗り越える必要があります。
###エラー
sh: -c: line 0: syntax error near unexpected token `(' sh: -c: line 0: `python /usr/lib/python3.5/フルPATH/polly.py Unable to locate credentials. You can configure credentials by running "aws configure".
↑
こちらは、WEBブラウザ上からEXEC(python /usr/lib/python3.5/フルPATH/polly.py);が記載してあるPHPファイルを開いて表示させた時のエラーです。
###頂くアンサーの方向性
今回は、AWSのエラーが出ているため、AWS configure/IAM関連のアドバイスも歓迎なのですが、
上記の通り、PHPからPythonをexecで動かした時に、AWS動作以前に、ファイル生成(touch)すら動作しなくなる現象の、根本原因を理解したいのです。
(EC2に移動すれば解消するようであれば、引っ越しします)
但し、PHP pythonをまたぐとファイル生成もできない現象は、aws利用の時に限りません。
まずは、
実行ユーザーとは?
どこでコントロールできるのか?
PHP echo get_current_user;でroot/apacheと表示されたらpython側でどう対応すれば良いか?
といった概念を私が理解する必要があります。
ちなみに、
コマンドラインからpython経由で生成したファイルのユーザー/グループはroot。
PHP経由でpythonを実行した際(動作しない時)は、apacheです。
PHPからPythonを使い始めた当初から、ハマり続けています。
このまるまる1日一つのバグで前に進まない状況を抜け出したいと考えています。
試した事4
※2/23 14:32追記(試した事):->参考URL2から原因究明を進め、
コマンドラインから下記を実行
polly.py
1i3 = 'aws sts get-caller-identity' 2out = subprocess.check_output(i3, shell=True) 3print (out) 4 5file3 = '/var/www/html/t4/hoge.txt' 6Path(file3).touch() 7 8with open(file3,'w', encoding='utf8') as f2: 9 print(out, file=f2) 10 11#結果:b'{'UserId': 'xxxxxxxxxxxx', 'Arn': 'arn:aws:iam::xxxxxxxxxxxx:root', 'Account': 'xxxxxxxxxxxxxx'}
polly.php
1<?php 2$command="aws sts get-caller-identity --region us-west-1"; 3exec($command,$output); 4print "$output[0]\n"; 5print_r($output); 6var_dump ($output); 7 8$command="python /usr/lib/python3.5/site-packages/polly/polly2.py $keywords $dir $manu $filepath"; 9exec($command,$output); 10print "$output[1]\n"; 11print_r($output); 12var_dump ($output); 13?> 14//HTTPの結果:bool(true) array(0) { } int(0)
と、PHPファイルをブラウザからURL表示して、execで全く同じpythonファイルを実行させたときのエラー(PHP側からは実行ユーザーの表示すらないように見える)
[Sun Feb 23 14:44:13.128866 2020] [php7:notice] [pid 3206] [client 61.210.204.156:56533] PHP Notice: Undefined offset: 1 in /var/www/html/polly.php on line 353, referer: /polly.php Unable to locate credentials. You can configure credentials by running "aws configure". Unable to locate credentials. You can configure credentials by running "aws configure". Traceback (most recent call last): File "/usr/lib/python3.5/site-packages/polly/polly2.py", line 36, in <module> out = subprocess.check_output(ahoi3, shell=True) File "/usr/lib64/python3.5/subprocess.py", line 316, in check_output **kwargs).stdout File "/usr/lib64/python3.5/subprocess.py", line 398, in run output=stdout, stderr=stderr) subprocess.CalledProcessError: Command 'aws sts get-caller-identity' returned non-zero exit status 255
試した事5
CENTOS7でservice httpd restartではなくsystemctl restart httpdのため、冒頭の参考URL2の通り試せない。代わりに、
vim /etc/sysconfig/httpd
から環境変数を確認するも、LANG=Cとだけしか指定されていないので、分からないなりにLANG=JPにしておいた。
※意味なし。依然としてPHP側からのAWS CLI実行は動作せず。
試した事6
AWS Linuxインスタンス上PHPのexec()でコマンドを使いたい
https://teratail.com/questions/162256
という同様の質問を参考に、
polly.php
1<?php 2putenv('AWS_DEFAULT_REGION=' . $region); 3putenv('AWS_ACCESS_KEY_ID=' . $key); 4putenv('AWS_SECRET_ACCESS_KEY=' . $secret); 5$command="aws sts get-caller-identity --region us-west-1"; 6exec($command,$output); 7print "$output[0]\n"; 8print_r($output); 9var_dump ($output); 10 11 12//HTML出力結果 13Array 14( 15 [0] => { 16 [1] => "Account": "xxxxxxxxxxxx", 17 [2] => "Arn": "arn:aws:iam::xxxxxxxxxxxx:root", 18 [3] => "UserId": "xxxxxxxxxxxx" 19 [4] => } 20)
と、適切な(仮:rootは適切ではないが、コマンドライン実行時と同じ)ユーザーでPHPのHTML出力結果でも表示された。一歩進んだ、ような気がする。
(参考URL2)の
https://note.com/garugarion/n/n42c6f24dc892
>要注意なのがコマンドラインで$ printenv を実行するとUSERは適切なログインユーザーになっているところ。このせいで原因究明が遅れます。
、、という箇所まで来た、のではないかと考えている(しかし引き続き、polly.pyがコマンドラインでは正確に実行され、PHPからのexec実行では動作しない現象は続いている。)
あと一押し、お知恵を頂けると嬉しいです。
何卒宜しくお願い申し上げます。
回答2件
あなたの回答
tips
プレビュー