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

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

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

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Python

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

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

解決済

2回答

2839閲覧

【初心者】PHPからPython(でAWS CLI)を実行する際に、実行ユーザーの違いからファイル生成すらできなくなる現象を解消したい

minamino

総合スコア7

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Python

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

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

0グッド

1クリップ

投稿2020/02/22 16:34

編集2020/02/23 08:25

※初心者がハマっていく過程が長文で書いてありますので、
お急ぎの方は下部の自己解決の回答を先にお読みください。

初心者です。
###参考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実行では動作しない現象は続いている。)

あと一押し、お知恵を頂けると嬉しいです。

何卒宜しくお願い申し上げます。

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

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

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

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

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

hayataka2049

2020/02/22 16:42 編集

exec("python /PATH/polly.py");ってしたときのpythonとコマンドラインで実行したときのpythonは同じものですか? あとエラーメッセージは何をしたときにどこで得られたものですか?
minamino

2020/02/22 16:51

ありがとうございます。修正しました。 あまりにもハマって消耗してしまったので一旦寝ます。
otn

2020/02/22 16:52

pythonもフルパスで指定してみてください。
otn

2020/02/22 17:07

コードを囲むのは、"""じゃなくて```です。
otn

2020/02/22 18:07 編集

PHPコードは改変せず、ファイル全体を丸ごとコピペしてください。 少なくとも、sh: -c: line 0: のエラーの原因はPHPコード内です。
hoshi-takanori

2020/02/22 21:04 編集

エラ〜メッセージに aws configure しろと書いてありますが、aws configure の結果はそれを実行したユーザーのホームディレクトリに置かれます。 https://utano.jp/entry/2015/06/aws-cli-configure-credentials-path/ ので、目的の puthon スクリプトを動かすユーザーで aws configure するか、自分(aws configure 済みの)のユーザーで python スクリプトが動くようにする必要があります。 なお、自分が何をしているかを理解せずにセキュリティを変更(visudo など)するのは非常に危険ですので、Linux のセキュリティモデルをきちんと勉強することをお勧めします。さもないと AWS のクレデンシャルを盗まれて 100 万単位の請求書が届くことになります。
minamino

2020/02/23 00:49

->otnさん ありがとうございます。丸ごとコピペします。 『pythonもフルパスで』は、python側PHP側どちらの、どの記述を指していますか? ->hoshitakanoriさん ありがとうございます。確認します。リスクの事も意識してませんでした。勉強になります。
otn

2020/02/23 01:09

> 『pythonもフルパスで』は、python側PHP側どちらの、どの記述を指していますか? $tmp2=exec("python /usr/lib/python3.5/フルPATH/polly.py"); のことです。
退会済みユーザー

退会済みユーザー

2020/02/23 03:00

@oth そもそも *.py の1行目に実行するためのパスをかいてるからむしろそこの python は記載を消すべきじゃね
minamino

2020/02/23 03:34

@otn さん @asahina さん ありがとうございます。そうなんです。 シバンに #!/usr/bin/python3.5 と書いてあるので、 exec("python {$pythonに渡す環境変数(/usr/bin/python3.5/ ?)} /usr/lib/python3.5/フルPATH/polly.py"); と書いても変化はありませんでした。 @hayatakaさん エラーメッセージは、 /var/log/httpd/error_log で見ています。コマンドラインではエラーは出ず実行されますし、ブラウザからPHPファイルをURL指定して開いても、PHPのエラーしか表示されないためです(ちゃんとしたデバグ環境が必要だと痛感します) @hoshitakanoriさん >自分(aws configure 済みの)のユーザーで python スクリプトが動くようにする必要があります。 コマンドラインからですと、自分(aws configure 済みの)のユーザーで python スクリプトが動きます。なぜ、PHPファイルをブラウザからURL表示して、exec経由で全く同じフルパスのpythonファイルを開いても、実行されないのか?、がポイントです。 rootかapacheか、のユーザーの違いだと考えているのですが、どこでコントロールすれば良いのかが分からないのです。
hoshi-takanori

2020/02/23 03:52

根本原因を理解したいのであれば apache や php や python よりもはるか以前に、Linux のユーザーを理解する必要があります。ちなみに、「コマンドラインからpython経由で生成したファイルのユーザー/グループはroot。」ってのはセキュリティ的に危険なので、まず自分のユーザーを作って、root ではログインできなくするのがお勧めです。(が、間違ってログインや sudo できなくならないようにご注意を。)
minamino

2020/02/23 03:58

@hoshiさん ありがとうございます。ユーザーの概念の理解から進めます。 >rootではログインできなくする そうですよね、、PORTも22のまま運用してたら先日外部から2000回ほどログイン試行されてサーバにアクセスできなくなりました。 さて、下記のURLが該当するかもしれません。 https://note.com/garugarion/n/n42c6f24dc892 (只今検証中)
minamino

2020/02/23 07:23

動きました。いま、特定中です
otn

2020/02/23 07:32

> この python は記載を消すべきじゃね それで解決するかもしれませんが、そうなると原因不明のままです。 何度も言いますが、minaminoさん、execのpythonをフルパスで書いて実行してみてください。
minamino

2020/02/23 08:18

@otnさん ありがとうございます。 後学のためにこの場合のotnさんの言う、フルパス、とは $cmd=exec("python /usr/lib/python3.5/site-packages/polly/polly.py"); の事でしょうか? それとも、 (仮:文法不明)$cmd=exec("python /usr/bin/python3/ /usr/lib/python3.5/site-packages/polly/polly.py"); のようにpythonの実行環境指定を含む意味でしょうか? いずれにしても、お礼申し上げます。
otn

2020/02/23 08:26

「pythonをフルパスで」の意味自体が通じていないとは思ってませんでした。 $cmd=exec("/path/to/python /usr/lib/python3.5/site-packages/polly/polly.py"); のように書くという意味です。 実際に何と書くかは、コマンドラインで type python で調べてください。
minamino

2020/02/23 08:48 編集

ありがとうございます。以下の通りの実行結果でした。 ************************** ◆1:type python $cmd=exec("/usr/local/bin/python /usr/lib/python3.5/site-packages/polly/polly.py"); ◆2:type python3 $cmd=exec("/usr/bin/python3 /usr/lib/python3.5/site-packages/polly/polly.py"); ************************ 今回は、python3.5のため◆2ですね。 (上記も含め検証したのですが今回はputenvが要因だったため)今後のデバッグに役立てます。 すみません自己解決回答が2個になってますが、1個目は書きかけで削除依頼中です。週明けには運営さんが消してくれると思います。よくある情報探索上の流れとして、たまたまotnさんの以前の回答が見つかったため、他意無く言及しました。まったく意図せず、攻撃的とも解釈されかねない書き方になってしまったため、2個目を正とさせてください。 重ね重ねありがとうございました。
otn

2020/02/23 08:58

Pythonをフルパスで書いて、sh: -c: line 0: ~~ のエラーメッセージが出ますか?
otn

2020/02/23 09:03

その質問の私の回答では、当初のエラーは解消したが、別のエラーになったということで、問題自体は解決してませんが、なぜかベストアンサーになってしまっているようです。
minamino

2020/02/23 09:28

そんなご事情があったんですね。理解しました。 Pythonをフルパスで書くパターンと書かないパターン、いずれも sh: -c: line 0: ~~ のエラーメッセージ は出ませんでした。影響するケースがあるという事を教えて頂いたので、今後注意します。ご指導ありがとうございました。
otn

2020/02/23 09:55

あれ?いつのまにか出なくなったんですね。 原因不明のままか。
minamino

2020/02/23 10:55

すみません、原因としてましては sh: -c: line 0: syntax error near unexpected token `(' は、PHPのexec();の末尾でpython宛に渡していた引数にシングルクオート等々の禁則文字(仮)が含まれていた事が原因でした。'Hello'などとシンプルな文字列にしたところ消えています。 よって、この質問のキモは、 Unable to locate credentials. You can configure credentials by running "aws configure". の方だったという事になります。
otn

2020/02/23 11:03

ああ、やはり、PHPコードが改変されてなければ、sh -c のエラーについては、一瞬で解決です。
guest

回答2

0

PHP

1 2<?php 3putenv('AWS_DEFAULT_REGION=' . $region); 4putenv('AWS_ACCESS_KEY_ID=' . $key); 5putenv('AWS_SECRET_ACCESS_KEY=' . $secret); 6

を、execの直前に追記したら動作した。
python初心者が必ずハマると言われているUnicodeエラーも解消。

投稿2020/02/25 00:39

minamino

総合スコア7

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

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

0

2重投稿のため削除。

投稿2020/02/23 08:07

編集2020/02/23 08:56
minamino

総合スコア7

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問