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

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

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

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

Python

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

Q&A

解決済

2回答

9250閲覧

サブプロセスでsudo lsusbを実行したいのですが、現状落ちてしまいます。

morutemu

総合スコア45

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

Python

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

0グッド

0クリップ

投稿2017/05/30 10:58

編集2017/05/30 11:01

USBの給電制御するようなプログラムです。

OS:Lubuntu16.04
python:3.52

エラー内容

Traceback (most recent call last):
File "/home/ユーザー名/USB給電制御.py", line 102, in <module>
ret = subprocess.check_output(cmd, shell = True)
File "/usr/lib/python3.5/subprocess.py", line 626, in check_output
**kwargs).stdout
File "/usr/lib/python3.5/subprocess.py", line 708, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command 'sudo lsusb' returned non-zero exit status 1

ソースは以下の通りです。

python

1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4# ++++++++++++++++++++++++++++++++++++++++ モジュール +++++ 5from tkinter import * 6from tkinter import ttk 7from time import * 8import subprocess 9 10# ++++++++++++++++++++++++++++++++++++++++ ウィンドウ +++++ 11root = Tk() 12root.geometry('350x200') 13root.title('USB給電制御') 14root.option_add('*font', ('Helvetica', 10)) 15root.resizable(0,0) 16 17# ++++++++++++++++++++++++++++++++++++++++ 関 数 +++++ 18# 現在時刻の処理 19def CurrentTime(): 20 # グローバル変数を指定 21 global currentTime 22 global onTime 23 global offTime 24 # 現在時刻をセットする 25 currentTimeVal.set(strftime('%H:%M:%S')) 26 # ON/OFF時間を代入する 27 onHour = onHourVal.get() 28 onMin = onMinVal.get() 29 onSec = onSecVal.get() 30 offHour = offHourVal.get() 31 offMin = offMinVal.get() 32 offSec = offSecVal.get() 33 # 現在・ON/OFF時間をグローバル変数に代入する 34 currentTime = currentTimeVal.get() 35 onTime = onHour + ':' + onMin + ':' + onSec 36 offTime = offHour + ':' + offMin + ':' + offSec 37 # 一定時間で繰り返す 38 root.after(1000, CurrentTime) 39 40# ON/OFFの処理 41def powerProc(power): 42 # コマンドリストを初期化 43 cmdList = [] 44 # 選択されているHUB名称を取得 45 hubName = hubNameVal.get() 46 # HUB選択で初期項目(選択してください)だった場合 47 if hubName == initialHubName: 48 return 49 # コマンドリストを作成する 50 for i in retList: 51 # バス・デバイス・ポート番号を取り出す 52 bus = i[4:7].lstrip('0') 53 device = i[15:18].lstrip('0') 54 port = portVal.get() 55 # マッチングするリスト番号を特定 56 if i.find(hubName) > -1: 57 matchIndex = retList.index(i) 58 # コマンドに当てはめてリストに保存する 59 cmdList.append('sudo ./hub-ctrl -b ' + bus + ' -d ' + device + ' -P ' + port + ' -p ' + power) 60 # コマンドを実行する 61 subprocess.call(cmdList[matchIndex], shell=True) 62 63# 指定時間ONの処理 64def TimeOn(): 65 # ONにチェックが入っている場合 66 if onVal.get(): 67 # 指定時間ONと現在時刻が一致した場合 68 if onTime == currentTime: 69 # ON 70 power = '1' 71 powerProc(power) 72 # 一定時間で繰り返す 73 root.after(1000, TimeOn) 74 75# 指定時間OFFの処理 76def TimeOff(): 77 # OFFにチェックが入っている場合 78 if offVal.get(): 79 # 指定時間OFFと現在時刻が一致した場合 80 if offTime == currentTime: 81 # OFF 82 power = '0' 83 powerProc(power) 84 # 一定時間で繰り返す 85 root.after(1000, TimeOff) 86 87# 強制ONの処理 88def ForceOn(): 89 # ON 90 power = '1' 91 powerProc(power) 92 93# 強制OFFの処理 94def ForceOff(): 95 # OFF 96 power = '0' 97 powerProc(power) 98 99# ++++++++++++++++++++++++++++++++++++++++ 初期動作 +++++ 100# 入力コマンドのセット 101cmd = 'sudo lsusb' 102ret = subprocess.check_output(cmd, shell = True) 103# 結果をデコードしてStringに変換 104decRet = ret.decode('utf-8') 105# 最後の\nを削除 106slcRet = decRet[:-1] 107# \nで区切ってリストに入れる 108retList = slcRet.replace("'","").split('\n') 109# 区切ったリストの文字からBus・Device・IDを削除する 110retNameList = [val[33:] for val in retList] 111 112# ++++++++++++++++++++++++++++++++++++++++ 変 数 +++++ 113# ラベル 114currentTimeVal = StringVar() 115 116# コンボボックス 117hubNameVal = StringVar() 118initialHubName = '選択して下さい' 119hubNameVal.set(initialHubName) 120 121# チェックボックス 122onVal = BooleanVar() 123offVal = BooleanVar() 124onVal.set(True) 125offVal.set(True) 126onCheck = '' 127offCheck = '' 128 129# スピンボックス 130portVal = StringVar() 131onHourVal = StringVar() 132onMinVal = StringVar() 133onSecVal = StringVar() 134offHourVal = StringVar() 135offMinVal = StringVar() 136offSecVal = StringVar() 137onHourVal.set('06') 138onMinVal.set('00') 139onSecVal.set('00') 140offHourVal.set('18') 141offMinVal.set('30') 142offSecVal.set('00') 143 144# その他 145currentTime = '' 146onTime = '' 147offTime = '' 148 149# ++++++++++++++++++++++++++++++++++++++++ リスト +++++ 150# コマンド 151cmdList = [] 152 153# ラベル 154labelPositions = [ 155 {'text' : '現在時刻', 'textvariable' : '', 'x' : 30, 'y' : 20}, 156 {'text' : '対象HUB/Port', 'textvariable' : '', 'x' : 30, 'y' : 50}, 157 {'text' : ':', 'textvariable' : '', 'x' : 164, 'y' : 80}, 158 {'text' : ':', 'textvariable' : '', 'x' : 213, 'y' : 80}, 159 {'text' : ':', 'textvariable' : '', 'x' : 164, 'y' : 110}, 160 {'text' : ':', 'textvariable' : '', 'x' : 213, 'y' : 110}, 161 {'text' : '', 'textvariable' : currentTimeVal, 'x' : 130, 'y' : 20} 162] 163 164# コンボボックス 165comboboxPositions = [ 166 {'values' : retNameList, 'textvariable' : hubNameVal, 'state' : 'readonly', 'width' : 17, 'x' : 130, 'y' : 50} 167] 168 169# ボタン 170buttonPositions = [ 171 {'text' : '強制ON', 'command' : ForceOn, 'width' : 8, 'x' : 130, 'y' :150}, 172 {'text' : '強制OFF', 'command' : ForceOff, 'width' : 8, 'x' : 230, 'y' :150} 173] 174 175# チェックボックス 176checkButtonPositions = [ 177 {'varName' : onCheck, 'text' : 'ON', 'variable' : onVal, 'x' : 30, 'y' : 80}, 178 {'varName' : offCheck, 'text' : 'OFF', 'variable' : offVal, 'x' : 30, 'y' : 110} 179] 180 181# スピンボックス 182spinBoxPositions = [ 183 {'from' : 1, 'to' : 4, 'increment' : 1, 'format' : '', 'textvariable' : portVal,'with' :2, 'x' : 280, 'y' : 50}, 184 {'from' : 0, 'to' : 23, 'increment' : 1, 'format' : '%02.0f', 'textvariable' : onHourVal, 'with' :2, 'x' : 130, 'y' : 80}, 185 {'from' : 0, 'to' : 59, 'increment' : 1, 'format' : '%02.0f', 'textvariable' : onMinVal, 'with' :2, 'x' : 180, 'y' : 80}, 186 {'from' : 0, 'to' : 59, 'increment' : 1, 'format' : '%02.0f', 'textvariable' : onSecVal, 'with' :2, 'x' : 230, 'y' : 80}, 187 {'from' : 0, 'to' : 23, 'increment' : 1, 'format' : '%02.0f', 'textvariable' : offHourVal, 'with' :2, 'x' : 130, 'y' : 110}, 188 {'from' : 0, 'to' : 59, 'increment' : 1, 'format' : '%02.0f', 'textvariable' : offMinVal, 'with' :2, 'x' : 180, 'y' : 110}, 189 {'from' : 0, 'to' : 59, 'increment' : 1, 'format' : '%02.0f', 'textvariable' : offSecVal, 'with' :2, 'x' : 230, 'y' : 110} 190] 191 192# ++++++++++++++++++++++++++++++++++++++++ オブジェクトの配置 +++++ 193# ラベル 194for i in labelPositions: 195 Label(root, text = i['text'], textvariable = i['textvariable']).place(x = i['x'], y = i['y']) 196 197# コンボボックス 198for i in comboboxPositions: 199 ttk.Combobox(root, values = i['values'], textvariable = i['textvariable'], state = i['state'], width = i['width']).place(x = i['x'], y = i['y']) 200 201# ボタン 202for i in buttonPositions: 203 Button(root, text = i['text'], command = i['command'], width = i['width']).place(x = i['x'], y = i['y'] ) 204 205## チェックボックス 206for i in checkButtonPositions: 207 i['varName'] = Checkbutton(text = i['text'], variable = i['variable']).place(x = i['x'], y = i['y']) 208 209# スピンボックス 210for i in spinBoxPositions: 211 Spinbox(root, from_ = i['from'], to = i['to'], increment = i['increment'], format = i['format'], textvariable =i['textvariable'], width = i['with']).place(x = i['x'], y = i['y'] ) 212 213# ++++++++++++++++++++++++++++++++++++++++ 関 数 +++++ 214# 現在時刻 215CurrentTime() 216 217# 指定時間ON 218TimeOn() 219 220# 指定時間OFF 221TimeOff() 222 223# ++++++++++++++++++++++++++++++++++++++++ ウィンドウ表示 +++++ 224root.mainloop() 225

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

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

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

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

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

guest

回答2

0

ベストアンサー

これは結構難しい問題です。

lsusbが0以外を返すのは間違いなく、管理者権限が取れていないためです。

回避する方法は色々あります。

  • subprocessstdinにパスワードを流し込む方法
  • python自体に管理者権限をもたせる方法

この方法で最も汎用性があるのはsubprocessstdinにパスワードを流し込む方法ですが、Tkinterでパスワード入力画面を作って、stdinに流し込む必要があります。
非常に面倒ですが、どのディストリビューションでも動く汎用性があります。

もうひとつはpython自体に管理者権限をもたせる方法です。
こちらは簡単ですが、ディストリビューションごと(正確にはWindowManagerごと)に方法が違います。

Lubuntuでは以下のコマンドでスクリプトを起動すればよいと思います。

gksudo ./USB給電制御.py

ちなみにopenSUSE+KDEですと、以下のコマンドになります。

kdesu ./USB給電制御.py

このコマンドで起動すると、GUIで管理者パスワードを求めてきますので入力してください。
ですので適当なshファイルを作成して、上記のコマンドを書いてください。

少なくともopenSUSEでは、この方法でDolphinからダブルクリックで起動できました。

投稿2017/05/30 14:25

編集2017/05/31 02:39
pashango2

総合スコア930

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

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

morutemu

2017/05/30 21:54 編集

前回といい、非常にわかりやすい解説ありがとうございます。 初めてpythonを触り、初めて自分でプログラムを組んだものなので、現状パスワードを入れる高度なことはちょっと少し難しそうなので、後者のpython自体に管理者権限をもたせる方法を実施してみました。 kdesudo ./USB給電制御.py で実行してみたところパスワード入力画面が出てきて、パスワードはできました。 しかし、ターミナルに文字化けしたものが出てきてしまい、ダブルクリックでの起動はできませんでした。
pashango2

2017/05/30 22:43

最後のkdesuだけ試してみてください。 まぁ、この問題はPythonというよりLinux(KDE)の問題なので難しいですね。
morutemu

2017/05/31 07:27

kdesu:コマンドが見つかりません と、出てきました
pashango2

2017/05/31 22:26 編集

gksudoはどうでしょうか? これなら行けると思います。
morutemu

2017/06/02 16:36

すみません、回答していただいていたのに、遅くなりました。 gksudo ./USB給電制御.py こちらで実行してみました。 一応パスワードを入れるところまではでき、文字化けも出ませんでした。 ただ、ダブルクリックでの実行はできませんでした。 前にも教えていただいたパスワードを入力する方法を考えるしかなさそうですね。
pashango2

2017/06/02 23:35 編集

うーん、それでいけるはずなんですが・・ .shファイルを作りましたよね? .shファイルをダブルクリックでいけませんか? .shファイルを作っても.pyをダブルクリックしていたのでは意味がありませんよ?
morutemu

2017/06/03 00:13

.shファイルを作るのは知りませんでした。。 で、一応調べてやってみたんですが、うまくいきませんでした。 ◆手順 ①shellファイルを作成 USB給電制御.sh(home/ユーザーネーム/デスクトップにあります) 中身: #!/bin/gksu root sudo python /home/ユーザーネーム/ USB給電制御.py ②実行ファイルにする chmod +x USB給電制御.sh ③USB給電制御.shをダブルクリックして起動 ウィンドウを起動 実行 ⇒ 起動せず 端末で実行 ⇒ ターミナルが出て来ましたが、特に何も起こりませんでした。
pashango2

2017/06/03 02:17

shファイルの中身は gksudo /home/ユーザーネーム/ USB給電制御.py で良いはずです。
morutemu

2017/06/03 03:51 編集

shファイルを USB給電制御.sh gksudo /home/ユーザーネーム/ USB給電制御.py にして実行してみたところ。 Enter your password to perform administrative tasks The application '/home/ユーザーネーム/'USB給電制御'' lets you modify essential partss of your system とパスワード入力を求められ入力してましたが、ダメでした。
pashango2

2017/06/05 11:35

基本的に"gksudo xxx.py"がターミナル上で実行可能であれば、それを.shファイルにしただけなので、同じ動作をするはずなんですが・・・ これ以上は私にはわかりません、あと少しな気がするのですが・・・ 力になれなくて申し訳ありません。
morutemu

2017/06/07 08:48 編集

いえいえ、こんなに尽力していただきありがとうございます。 一応パソコン得意な友人に聞いたところ、.desktopで起動できるようでした。 [Desktop Entry] Type=Application Terminal=true Name=USB給電制御 Icon=utilities-terminal Exec=lxterminal -e "bash -c 'sudo -s python3 /home/ユーザー名/USB給電制御.py;$SHELL'" Categories=Application;
pashango2

2017/06/08 00:36

起動できるようになってよかったです。 最初、LubuntuをKubuntuと勘違いしており、再現できない環境で回答してしまったため、心配しておりました。 勉強になります。
guest

0

コードを書きたかったので回答欄を使います。以下のコードをの実行結果が原因を突き止めるために有用だと思います。

python

1from subprocess import run 2from subprocess import PIPE 3 4 5try: 6 print(run('sudo lsusb', stdout=PIPE, stderr=PIPE)) 7except Exception as e: 8 print(e) 9 print(e.args)

投稿2017/05/30 12:19

編集2017/05/30 12:22
YouheiSakurai

総合スコア6142

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問