スクリプトを実行するたびにVirtualBox共有フォルダーをマウントする小さなスクリプトを作成しようとしています。 Pythonでそれをやりたいのは、スクリプトのためにそれを学ぼうとしているからです。
問題は、mountコマンドを起動するために特権が必要なことです。スクリプトをSudoとして実行することもできますが、Sudoを独自に作成することを好みます。
パスワードを.pyファイルに書き込むのは安全ではないことは既に知っていますが、重要ではない仮想マシンについて説明しています。pyスクリプトをクリックして機能させるだけです。
これは私の試みです:
#!/usr/bin/env python
import subprocess
sudoPassword = 'mypass'
command = 'mount -t vboxsf myfolder /home/myuser/myfolder'
subprocess.Popen('Sudo -S' , Shell=True,stdout=subprocess.PIPE)
subprocess.Popen(sudoPassword , Shell=True,stdout=subprocess.PIPE)
subprocess.Popen(command , Shell=True,stdout=subprocess.PIPE)
My pythonバージョンは2.6
_sudoPassword = 'mypass'
command = 'mount -t vboxsf myfolder /home/myuser/myfolder'
p = os.system('echo %s|Sudo -S %s' % (sudoPassword, command))
_
これを試して、動作するかどうかを教えてください。 :-)
そしてこれは:
os.popen("Sudo -S %s"%(command), 'w').write('mypass')
多くの回答はソリューションを機能させる方法に焦点を当てていますが、ソリューションが非常に悪いアプローチであることを示唆するものはほとんどありません。あなたが本当に「学ぶ練習」をしたいなら、良い解決策を使って練習してみませんか?パスワードをハードコーディングすると、 wrong アプローチが学習されます!
本当に必要なのがそのボリュームのパスワードなしのmount
である場合、多分Sudo
は必要ありません at /!他のアプローチを提案できますか?
/etc/fstab
を mensi として使用します。オプションuser
およびnoauto
を使用して、通常のユーザーがそのボリュームをマウントできるようにします。
パスワードなしのアクションにはPolkit
を使用します。.policy
を使用してスクリプトの<allow_any>yes</allow_any>
ファイルを構成し、/usr/share/polkit-1/actions
にドロップします
/etc/sudoers
を編集して、ユーザーがパスワードを入力せずにSudo
を使用できるようにします。
上記のすべてでパスワードなしのルート権限が許可されますが、パスワードをハードコードする必要はありません。任意のアプローチを選択してください。詳細を説明できます。
why に関しては、パスワードをハードコーディングすることは非常に悪い考えです。さらに読むためのいくつかの良いリンクがあります。
Sudo
のstdinにパスワードを渡すには:
#!/usr/bin/env python
from subprocess import Popen, PIPE
Sudo_password = 'mypass'
command = 'mount -t vboxsf myfolder /home/myuser/myfolder'.split()
p = Popen(['Sudo', '-S'] + command, stdin=PIPE, stderr=PIPE,
universal_newlines=True)
Sudo_Prompt = p.communicate(Sudo_password + '\n')[1]
注:おそらくパスワードなしのSudoまたはSudo_ASKPASS
コマンドをソースコードにパスワードをハードコーディングする代わりに使用します。
端末デバイスの代わりに「stdin」からパスワードを読み取るように指示するSudoコマンドで-Sオプションを使用します。
PIPEからstdinを読み込むようPopenに指示します。
パスワードを通信メソッドへの引数として使用して、プロセスのstdin PIPEにパスワードを送信します。パスワードの最後に改行文字「\ n」を追加することを忘れないでください。
sp = Popen(cmd , Shell=True, stdin=PIPE)
out, err = sp.communicate(_user_pass+'\n')
subprocess.Popen
はプロセスを作成し、パイプやものを開きます。あなたがしていることは:
Sudo -S
mypass
mount -t vboxsf myfolder /home/myuser/myfolder
これは明らかに機能しません。引数をPopenに渡す必要があります。 そのドキュメント を見ると、最初の引数は実際には引数のリストであることがわかります。
これをpython 3.5に使用しました。サブプロセスモジュールを使用して実行しました。このようなパスワードは非常にinsecureです。
subprocess モジュールはコマンドを文字列のリストとして受け取り、事前にsplit()を使用してリストを作成するか、リスト全体を渡します後。詳細については、ドキュメントを参照してください。
#!/usr/bin/env python
import subprocess
sudoPassword = 'mypass'
command = 'mount -t vboxsf myfolder /home/myuser/myfolder'.split()
cmd1 = subprocess.Popen(['echo',sudoPassword], stdout=subprocess.PIPE)
cmd2 = subprocess.Popen(['Sudo','-S'] + command, stdin=cmd1.stdout, stdout=subprocess.PIPE)
output = cmd2.stdout.read.decode()
モジュールpexpectを試してください。ここに私のコードがあります:
import pexpect
remove = pexpect.spawn('Sudo dpkg --purge mytool.deb')
remove.logfile = open('log/expect-uninstall-deb.log', 'w')
remove.logfile.write('try to dpkg --purge mytool\n')
if remove.expect(['(?i)password.*']) == 0:
# print "successfull"
remove.sendline('mypassword')
time.sleep(2)
remove.expect(pexpect.EOF,5)
else:
raise AssertionError("Fail to Uninstall deb package !")
Sudoとして実行するものを制限するには、次を実行できます。
python non_Sudo_stuff.py
Sudo -E python -c "import os; os.system('Sudo echo 1')"
パスワードを保存する必要はありません。 -E
パラメーターは、現在のユーザーのenvをプロセスに渡します。シェルには2番目のコマンドの後にSudo特権が付与されるため、注意して使用してください。
時にはキャリッジリターンが必要です:
os.popen("Sudo -S %s"%(command), 'w').write('mypass\n')
スクリプトでSudoパスワードをハードコードしないことが常に好ましいことを知っています。ただし、何らかの理由で、_/etc/sudoers
またはファイル所有者の変更、Pexpectは実行可能な代替手段です。
Python function Sudo_exec
ご参考までに:
import platform, os, logging
import subprocess, pexpect
log = logging.getLogger(__name__)
def Sudo_exec(cmdline, passwd):
osname = platform.system()
if osname == 'Linux':
Prompt = r'\[Sudo\] password for %s: ' % os.environ['USER']
Elif osname == 'Darwin':
Prompt = 'Password:'
else:
assert False, osname
child = pexpect.spawn(cmdline)
idx = child.expect([Prompt, pexpect.EOF], 3)
if idx == 0: # if prompted for the Sudo password
log.debug('Sudo password was asked.')
child.sendline(passwd)
child.expect(pexpect.EOF)
return child.before